Tengo un marco de datos indexado por fecha, con columnas de tamaño de inundación (0-3) y precipitación (ppt):

                Size    ppt
date
2017-09-11      0.0     0.000000
2017-09-12      0.0     0.000000
2017-09-13      0.0     0.000000
2017-09-14      1.0     34.709998
2017-09-15      0.0     0.000000
2017-09-16      0.0     0.000000
2017-09-17      0.0     0.000000
2017-09-18      0.0     0.600000
2017-09-19      3.0     157.439998

Necesito separar los datos de acuerdo a si ocurrió una inundación ('Tamaño' = 1,2 o 3), o no ocurrió una inundación ('Tamaño' = 0), para darme dos conjuntos separados de datos de precipitación asociados con la inundación o no inundar.

Aprecio que esto sea probablemente bastante básico, pero parece que no puedo encontrar las respuestas correctas ...

¡Gracias!

4
SHV_la 10 sep. 2018 a las 13:44

3 respuestas

La mejor respuesta

Utilice boolean indexing con máscara booleana invertida por ~:

mask = df['Size'].eq(0)
#alternative
#mask = df['Size'] == 0
df1 = df[~mask]
df2 = df[mask]

Editar:

Para el uso de máscaras booleanas múltiples:

m1 = df['Size'].eq(0)
m2 = df['ppt'].eq(0)

#alternative
#m1 = df['Size'] == 0
#m2 = df['ppt'] == 0

SizePos = df[m1 & m2]
dSizeZero_PptPosf2 = df[m1 & ~m2]
SizeZero_PptZero = df[~m1]

print (SizePos)
            Size  ppt
date                 
2017-09-11   0.0  0.0
2017-09-12   0.0  0.0
2017-09-13   0.0  0.0
2017-09-15   0.0  0.0
2017-09-16   0.0  0.0
2017-09-17   0.0  0.0

print (dSizeZero_PptPosf2)
            Size  ppt
date                 
2017-09-18   0.0  0.6

print (SizeZero_PptZero)
date                        
2017-09-14   1.0   34.709998
2017-09-19   3.0  157.439998
2
jezrael 10 sep. 2018 a las 12:17

groupby

Podemos iterar a través del objeto groupby después de agrupar por la evaluación booleana de Size siendo 0 o no. Cuando asignamos esto a otros nombres (df1, df2 = ...) el iterable resultante se divide en sus dos partes.

df1, df2 = (d for _, d in df.groupby(df.Size.eq(0)))

Imprimirlos para ver

print(df1, df2, sep='\n\n')

            Size         ppt
date                        
2017-09-14   1.0   34.709998
2017-09-19   3.0  157.439998

            Size  ppt
date                 
2017-09-11   0.0  0.0
2017-09-12   0.0  0.0
2017-09-13   0.0  0.0
2017-09-15   0.0  0.0
2017-09-16   0.0  0.0
2017-09-17   0.0  0.0
2017-09-18   0.0  0.6

Para fines de explicación

for name, d in df.groupby(df.Size.eq(0)):
  print(name, d, '=' * 40, sep='\n\n')

False

            Size         ppt
date                        
2017-09-14   1.0   34.709998
2017-09-19   3.0  157.439998

========================================
True

            Size  ppt
date                 
2017-09-11   0.0  0.0
2017-09-12   0.0  0.0
2017-09-13   0.0  0.0
2017-09-15   0.0  0.0
2017-09-16   0.0  0.0
2017-09-17   0.0  0.0
2017-09-18   0.0  0.6

========================================
2
piRSquared 10 sep. 2018 a las 11:38

Puede crear un diccionario de marcos de datos:

dfs = dict(tuple(df.groupby(np.where(df['Size'].eq(0), 'ppt_negative', 'ppt_positive'))))

El beneficio de este enfoque es que está vinculando explícitamente las estructuras de datos relacionadas, lo que puede ayudar a manipulaciones posteriores, transportabilidad, etc.

Resultado:

{'ppt_negative':          date  Size  ppt
                 0  2017-09-11   0.0  0.0
                 1  2017-09-12   0.0  0.0
                 2  2017-09-13   0.0  0.0
                 4  2017-09-15   0.0  0.0
                 5  2017-09-16   0.0  0.0
                 6  2017-09-17   0.0  0.0
                 7  2017-09-18   0.0  0.6,

 'ppt_positive':          date  Size         ppt
                 3  2017-09-14   1.0   34.709998
                 8  2017-09-19   3.0  157.439998}

Es posible una diferenciación más elaborada a través de np.select:

m1 = df['Size'].eq(0)
m2 = df['ppt'].eq(0)

conds = [m1 & m2, m1 & ~m2, ~m1]
choices = ['SizeZero_PptZero', 'SizeZero_PptPos', 'SizePos']

dfs = dict(tuple(df.groupby(np.select(conds, choices))))

Resultado:

{'SizePos':          date  Size         ppt
            3  2017-09-14   1.0   34.709998
            8  2017-09-19   3.0  157.439998,

 'SizeZero_PptPos':          date  Size  ppt
                    7  2017-09-18   0.0  0.6,

 'SizeZero_PptZero':          date  Size  ppt
                     0  2017-09-11   0.0  0.0
                     1  2017-09-12   0.0  0.0
                     2  2017-09-13   0.0  0.0
                     4  2017-09-15   0.0  0.0
                     5  2017-09-16   0.0  0.0
                     6  2017-09-17   0.0  0.0}
1
jpp 10 sep. 2018 a las 12:12