2017-10-18 38 views
1

我有一個人口數據。我想爲每個州和每個年份創建單獨的數據框。這個想法如下:在循環中創建多個數據框

for i in province_id: 
    for j in year: 
     sub_data_i_j = data[(data.provid==i) &(data.wave==j)] 

但是,我不知道如何動態生成sub_data_i_j。

回答

1

這應做到:

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'])} 
+0

我同意。第二種方法更pythonic。謝謝! –

2

我覺得最好是boolean indexinggroupby創建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} 
+0

而由我發佈你已經有了一個大的答案的時間...好+1 –

+0

大的答案嗎?我不明白... – jezrael

+0

我的意思是,當我完成我的「答案」時,你已經得到了一個例子和「其他解決方案」的答案。你很快 –

1

我的建議:

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]

+0

感謝您介紹defaultdict類。 –

相關問題