python pandas - 使用for循环

时间:2016-12-28 22:35:31

标签: python pandas

考虑以下2个3 dicts列表和3个空DataFrame

dict0={'actual': {'2013-02-20 13:30:00': 0.93}}
dict1={'actual': {'2013-02-20 13:30:00': 0.85}}
dict2={'actual': {'2013-02-20 13:30:00': 0.98}}
dicts=[dict0, dict1, dict2]

df0=pd.DataFrame()
df1=pd.DataFrame()
df2=pd.DataFrame()
dfs=[df0, df1, df2]

我想通过使用以下行来递归修改循环中的3个Dataframe:

for df, dikt in zip(dfs, dicts):
    df = df.from_dict(dikt, orient='columns', dtype=None)

但是,当尝试在循环外部检索df的1时,它仍然是空的

print (df0)

将返回

Empty DataFrame
Columns: []
Index: []

从for循环中打印df时,我们可以看到数据已正确附加。

如何制作循环以便可以在循环之外打印3个dfs?

6 个答案:

答案 0 :(得分:3)

这将使它完成到位!!!
注意 3个感叹号

一个班轮

[dfs[i].set_value(r, c, v)
 for i, dn in enumerate(dicts)
 for r, dr in dn.items()
 for c, v in dr.items()]; 

更直观

for d, df in zip(dicts, dfs):
    temp = pd.DataFrame(d).stack()
    for (r, c), v in temp.iteritems():
        df.set_value(r, c, v)

df0

                     actual
2013-02-20 13:30:00    0.93

等效替代
没有pd.DataFrame构造

for i, dn in enumerate(dicts):
    for r, dr in dn.items():
        for c, v in dr.items():
            dfs[i].set_value(r, c, v)

为什么会有所不同?
到目前为止,所有其他答案都将新数据帧重新分配给数据帧列表中的必要位置。他们破坏了那里的数据框架。原始数据框保留为空,而新的非空数据框放在列表中。

此解决方案编辑了数据框,确保使用新信息更新原始数据框。

每个OP:

  

但是,当尝试在循环外部检索df的1时,它仍然是空的

<强> 定时
它也快得多了

enter image description here

设置

dict0={'actual': {'2013-02-20 13:30:00': 0.93}}
dict1={'actual': {'2013-02-20 13:30:00': 0.85}}
dict2={'actual': {'2013-02-20 13:30:00': 0.98}}
dicts=[dict0, dict1, dict2]

df0=pd.DataFrame()
df1=pd.DataFrame()
df2=pd.DataFrame()
dfs=[df0, df1, df2]

答案 1 :(得分:2)

在循环中,df只是一个临时值,而不是对相应列表元素的引用。如果要在迭代时修改列表,则必须按索引引用列表。你可以使用Python的枚举:

来做到这一点
for i, (df, dikt) in enumerate(zip(dfs, dicts)):
    dfs[i] = df.from_dict(dikt, orient='columns', dtype=None)

答案 2 :(得分:1)

您需要保留对df对象的引用,因此您可以尝试:

for idx, dikt in enumerate(dicts):
    dfs[idx] = dfs[idx].from_dict(dikt, orient='columns', dtype=None)

答案 3 :(得分:0)

我没有解释为什么会这样。但是,解决方法是:

dict0={'actual': {'2013-02-20 13:30:00': 0.93}}
dict1={'actual': {'2013-02-20 13:30:00': 0.85}}
dict2={'actual': {'2013-02-20 13:30:00': 0.98}}
dicts=[dict0, dict1, dict2]

dfs = []

for dikt in dicts:
    df = df.from_dict(dikt, orient='columns', dtype=None)
    dfs.append(df)

现在

dfs[0]

返回

                     actual
2013-02-20 13:30:00    0.93

答案 4 :(得分:0)

一个班轮。

>>>df_list = [df.from_dict(dikt, orient='columns', dtype=None) for (df, dikt) in zip(dfs, dicts)]

>>>df_list
[                     actual
2013-02-20 13:30:00    0.93,
                      actual
2013-02-20 13:30:00    0.85, 
                      actual
2013-02-20 13:30:00    0.98]

>>>df_list[0]
                     actual
2013-02-20 13:30:00    0.93

答案 5 :(得分:0)

您还可以通过将数据帧放入字典中来完成此操作:

dfs = {
    'df0': df0,
    'df1': df1,
    'df2': df2
}

然后在for循环中调用并分配字典的内容。

for dfname, dikt in zip(dfs.keys(), dicts):
    dfs[dfname] = dfs[dfname].from_dict(dikt, orient='columns', dtype=None)

如果您仍然想按数据帧的名称(而不是列表中的任意索引...)来调用数据帧,这很有用

dfs['df0']