我有人口数据。我想为每个州和年创建单独的数据帧。这个想法如下:
for i in province_id:
for j in year:
sub_data_i_j = data[(data.provid==i) &(data.wave==j)]
但是,我不确定如何动态生成sub_data_i_j。
答案 0 :(得分:2)
我认为最好是使用groupby
创建dictionary of DataFrames
,然后先boolean indexing
过滤:
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}
最后,您可以选择每个DataFrame:
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 :(得分: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"
}
}
您可以通过例如:
访问数据帧d [1] [2013]
答案 2 :(得分:1)
这应该这样做:
for i in province_id:
for j in year:
locals()['sub_data_{}_{}'.format(i,j)] = data[(data.provid==i) & (data.wave==j)]
我最初建议使用exec
,出于安全原因,这通常不被视为最佳做法。话虽如此,如果你的代码没有暴露给任何有恶意的人,那应该没问题,为了完整起见,我会把它留在这里:
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'])}