我有一個人口數據。我想爲每個州和每個年份創建單獨的數據框。這個想法如下:在循環中創建多個數據框
for i in province_id:
for j in year:
sub_data_i_j = data[(data.provid==i) &(data.wave==j)]
但是,我不知道如何動態生成sub_data_i_j。
我有一個人口數據。我想爲每個州和每個年份創建單獨的數據框。這個想法如下:在循環中創建多個數據框
for i in province_id:
for j in year:
sub_data_i_j = data[(data.provid==i) &(data.wave==j)]
但是,我不知道如何動態生成sub_data_i_j。
這應做到:
for i in province_id:
for j in year:
locals()['sub_data_{}_{}'.format(i,j)] = data[(data.provid==i) & (data.wave==j)]
我最初使用exec
,這不是通常認爲爲安全起見最佳實踐建議。話雖這麼說,如果你的代碼不被暴露於與不懷好意的人,應該OK,我會離開這裏爲了完整起見:
for i in province_id:
for j in year:
exec "sub_data_{}_{} = data[(data.provid==i) & (data.wave==j)]".format(i,j)
然而,對於大多數使用情況下,它可能更好地使用某種類型的集合,例如一個字典,因爲在代碼的後續部分中引用動態生成的變量名會很麻煩。這也是一個班輪:
data_dict = {key:g for key,g in data.groupby(['provid','wave'])}
我覺得最好是boolean indexing
與groupby
創建dictionary of DataFrames
與過濾第一:
df = pd.DataFrame({'A':list('abcdef'),
'wave':[2004,2005,2004,2005,2005,2004],
'C':[7,8,9,4,2,3],
'D':[1,3,5,7,1,0],
'E':[5,3,6,9,2,4],
'provid':list('aaabbb')})
print (df)
A C D E provid wave
0 a 7 1 5 a 2004
1 b 8 3 3 a 2005
2 c 9 5 6 a 2004
3 d 4 7 9 b 2005
4 e 2 1 2 b 2005
5 f 3 0 4 b 2004
province_id = ['a','b']
year = [2004]
df = df[(df.provid.isin(province_id)) &(df.wave.isin(year))]
print (df)
A C D E provid wave
0 a 7 1 5 a 2004
2 c 9 5 6 a 2004
5 f 3 0 4 b 2004
dfs = {'{0[0]}_{0[1]}'.format(i) : x for i, x in df.groupby(['provid','wave'])}
另一種解決方案:
dfs = dict(tuple(df.groupby(df['provid'] + '_' + df['wave'].astype(str))))
print (dfs)
{'a_2004': A C D E provid wave
0 a 7 1 5 a 2004
2 c 9 5 6 a 2004, 'b_2004': A C D E provid wave
5 f 3 0 4 b 2004}
最後,你可以選擇每個數據幀:
print (dfs['b_2004'])
A C D E provid wave
5 f 3 0 4 b 2004
你的答案應該被改變:
sub_data = {}
province_id = ['a','b']
year = [2004]
for i in province_id:
for j in year:
sub_data[i + '_' + str(j)] = df[(df.provid==i) &(df.wave==j)]
print (sub_data)
{'a_2004': A C D E provid wave
0 a 7 1 5 a 2004
2 c 9 5 6 a 2004, 'b_2004': A C D E provid wave
5 f 3 0 4 b 2004}
而由我發佈你已經有了一個大的答案的時間...好+1 –
大的答案嗎?我不明白... – jezrael
我的意思是,當我完成我的「答案」時,你已經得到了一個例子和「其他解決方案」的答案。你很快 –
我的建議:
import io
import pandas as pd
from collections import defaultdict
string = u"""province_id,wave,value
1,2014,10
1,2014,10
1,2013,10
2,2010,10
3,2010,10"""
df = pd.read_csv(io.StringIO(string))
# Output:
d = defaultdict(dict)
# This splits the dataframe by province_id and wave
dfs = df.groupby(["province_id","wave"])
# Loop through the dataframes and stucture them
for ind,df in dfs:
d[ind[0]][ind[1]] = df
產生的字典結構是這樣的:
{
"1": {
"2013": "dataframe: 1 2013",
"2014": "dataframe: 1 2014"
},
"2": {
"2010": "dataframe: 2 2010"
},
"3": {
"2010": "dataframe: 3 2010"
}
}
而你通過訪問dataframes例如:
d [1] [2013]
感謝您介紹defaultdict類。 –
我同意。第二種方法更pythonic。謝謝! –