Dada una configuración como la siguiente:

import pandas as pd
import numpy as np

#Create random number dataframes
df1 = pd.DataFrame(np.random.rand(10,4))
df2 = pd.DataFrame(np.random.rand(10,4))
df3 = pd.DataFrame(np.random.rand(10,4))

#Create list of dataframes
data_frame_list = [df1, df2, df3]

#Introduce some NaN values
df1.iloc[4,3] = np.NaN
df2.iloc[1:4,2] = np.NaN

#Create loop to ffill any NaN values
for df in data_frame_list:
    df = df.fillna(method='ffill')

Esto todavía deja df2 (por ejemplo) como:

           0           1           2           3
0   0.946601    0.492957    0.688421    0.582571
1   0.365173    0.507617         NaN    0.997909
2   0.185005    0.496989         NaN    0.962120
3   0.278633    0.515227         NaN    0.868952
4   0.346495    0.779571    0.376018    0.750900
5   0.384307    0.594381    0.741655    0.510144
6   0.499180    0.885632    0.13413     0.196010
7   0.245445    0.771402    0.371148    0.222618
8   0.564510    0.487644    0.121945    0.095932
9   0.401214    0.282698    0.0181196   0.689916

Aunque la línea de código individual:

df2 = df2.fillna(method='ffill)

Funciona. Pensé que el problema podría deberse a la forma en que nombraba las variables, así que introduje global () [df], pero tampoco parecía funcionar.

¿Se pregunta si es posible completar un marco de datos completo en un bucle for, o me estoy equivocando en algún punto de mi enfoque?

1
Curious Student 31 oct. 2017 a las 15:26

3 respuestas

La mejor respuesta

Solo puede cambiar el DataFrame en la lista de DataFrames, por lo que df1 - df3 no se cambia con ffill y el parámetro inplace=True:

data_frame_list = [df1, df2, df3]
for df in data_frame_list:
    df.ffill(inplace=True)

print (data_frame_list)

[          0         1         2         3
0  0.506726  0.057531  0.627580  0.132553
1  0.131085  0.788544  0.506686  0.412826
2  0.578009  0.488174  0.335964  0.140816
3  0.891442  0.086312  0.847512  0.529616
4  0.550261  0.848461  0.158998  0.529616
5  0.817808  0.977898  0.933133  0.310414
6  0.481331  0.382784  0.874249  0.363505
7  0.384864  0.035155  0.634643  0.009076
8  0.197091  0.880822  0.002330  0.109501
9  0.623105  0.999237  0.567151  0.487938,           0         1         2         3
0  0.104856  0.525416  0.284066  0.658453
1  0.989523  0.644251  0.284066  0.141395
2  0.488099  0.167418  0.284066  0.097982
3  0.930415  0.486878  0.284066  0.192273
4  0.210032  0.244598  0.175200  0.367130
5  0.981763  0.285865  0.979590  0.924292
6  0.631067  0.119238  0.855842  0.782623
7  0.815908  0.575624  0.037598  0.532883
8  0.346577  0.329280  0.606794  0.825932
9  0.273021  0.503340  0.828568  0.429792,           0         1         2         3
0  0.491665  0.752531  0.780970  0.524148
1  0.635208  0.283928  0.821345  0.874243
2  0.454211  0.622611  0.267682  0.726456
3  0.379144  0.345580  0.694614  0.585782
4  0.844209  0.662073  0.590640  0.612480
5  0.258679  0.413567  0.797383  0.431819
6  0.034473  0.581294  0.282111  0.856725
7  0.352072  0.801542  0.862749  0.000285
8  0.793939  0.297286  0.441013  0.294635
9  0.841181  0.804839  0.311352  0.171094]
1
jezrael 31 oct. 2017 a las 12:31

No, desafortunadamente no. Está llamando fillna no en su lugar y se genera una copia, que luego se reasigna a la variable df. Debe comprender que reasignar esta variable no cambia el contenido de la lista.

Si desea hacer eso, repita el índice o use una lista de comprensión.

data_frame_list = [df.ffill() for df in data_frame_list]

O,

for i in range(len(data_frame_list)):
    data_frame_list[i].ffill(inplace=True)
2
cs95 31 oct. 2017 a las 13:29

O puedes concat

df=pd.concat([df1,df2,df3],keys=['df1','df2','df3'])

[x for _,x in df.groupby(level=0).ffill().groupby(level=0)]
1
YOBEN_S 31 oct. 2017 a las 12:36