2017-07-31 69 views
5

我试图从一个数据框中的一列随机分配值到12个不同类别(按年龄和性别)的另一个数据框。例如,我有两个数据框;让我们称之为一个D1和D2等如何在数据框之间随机分配值

d1: 
index agerange gender income 
0  2  1  56700 
1  2  0  25600 
2  4  0  3000 
3  4  0  106000 
4  3  0  200 
5  3  0  43000 
6  4  0  10000000 

d2: 
index agerange gender 
0  3  0  
1  2  0  
2  4  0  
3  4  0  

我想组中的两个dataframes由agerange和性别,即0-1,2,3,4,5,6 & 1-1,2,3,4-,然后在d1内随机选择一个收入并将其分配给d2。

即:

d1: 
index agerange gender income 
0  2  1  56700 
1  2  0  25600 
2  4  0  3000 
3  4  0  106000 
4  3  0  200 
5  3  0  43000 
6  4  0  10000000 

d2: 
index agerange gender income 
0  3  0  200 
1  2  0  25600 
2  4  0  10000000 
3  4  0  3000 

回答

4

选项1
np.random.choicepd.DataFrame.query
的一种方法我在做一个隐含的假设,即我们替换每行随机绘制的值。

def take_one(x): 
    q = 'agerange == {agerange} and gender == {gender}'.format(**x) 
    return np.random.choice(d1.query(q).income) 

d2.assign(income=d2.apply(take_one, 1)) 

     agerange gender income 
index       
0    3  0  200 
1    2  0 25600 
2    4  0 106000 
3    4  0 106000 

选项2
试图使其更有效地调用np.random.choice每组一次。

g = d1.groupby(['agerange', 'gender']).income.apply(list) 
f = lambda x: pd.Series(np.random.choice(g.get(x.name, [0] * len(x)), len(x)), x.index) 
d2.groupby(['agerange', 'gender'], group_keys=False).apply(f) 

     agerange gender income 
index        
0    3  0  200 
1    2  0  25600 
2    4  0 10000000 
3    4  0 106000 

调试和设置

import pandas as pd 
import numpy as np 

d1 = pd.DataFrame({ 
     'agerange': [2, 2, 4, 4, 3, 3, 4], 
     'gender': [1, 0, 0, 0, 0, 0, 0], 
     'income': [56700, 25600, 3000, 106000, 200, 43000, 10000000] 
    }, pd.Index([0, 1, 2, 3, 4, 5, 6], name='index') 
) 

d2 = pd.DataFrame(
    {'agerange': [3, 2, 4, 4], 'gender': [0, 0, 0, 0]}, 
    pd.Index([0, 1, 2, 3], name='index') 
) 

g = d1.groupby(['agerange', 'gender']).income.apply(list) 
f = lambda x: pd.Series(np.random.choice(g.loc[x.name], len(x)), x.index) 
d2.assign(income=d2.groupby(['agerange', 'gender'], group_keys=False).apply(f)) 

 agerange gender income 
index       
0    3  0  200 
1    2  0 25600 
2    4  0 106000 
3    4  0 3000 
+0

您好,我试图您的选项2的建议,并得到了错误** IndexingError:太多的索引**你有什么想法可能导致这个问题? – stav

+0

@kstav我添加了一个部分,您可以精确地复制和粘贴代码。如果它产生了期望的结果,那么问题出在你的特定数据框上。如果仍然存在问题,那么问题必须与版本或其他内容相关。 – piRSquared

+0

您发布的具体代码确实有效,我会看到根本问题可能是什么。谢谢 – stav

3

如何创建一个基于ageranges收入的字典,然后映射随机选择,即

#Based on unutbu's data 
df1 = pd.DataFrame({'agerange': [2, 2, 4, 4, 3, 3, 4], 'gender': [1, 0, 0, 0, 0, 0, 0], 'income': [56700, 25600, 3000, 106000, 200, 43000, 10000000], 'index': [0, 1, 2, 3, 4, 5, 6]}) 
df2 = pd.DataFrame({'agerange': [3, 2, 4, 4], 'gender': [0, 0, 0, 0], 'index': [0, 1, 2, 3]}) 

age_groups = df1.groupby('agerange')['income'].agg(lambda x: tuple(x)).to_dict() 
df2['income'] = df2['agerange'].map(lambda x: np.random.choice(age_groups[x])) 

输出:

 
    agerange gender index income 
0   3  0  0 43000 
1   2  0  1 25600 
2   4  0  2 106000 
3   4  0  3 106000 

如果性别组也需要那么你可以使用申请,如果你想填0的密钥没有找到你可以使用,如果否则即

df2 = pd.DataFrame({'agerange': [3, 2, 6, 4], 'gender': [0, 0, 0, 0], 'index': [0, 1, 2, 3]}) 
df1 = pd.DataFrame({'agerange': [2, 2, 4, 4, 3, 3, 4], 'gender': [1, 0, 0, 0, 0, 0, 0], 'income': [56700, 25600, 3000, 106000, 200, 43000, 10000000], 'index': [0, 1, 2, 3, 4, 5, 6]}) 


age_groups = df1.groupby(['agerange','gender'])['income'].agg(lambda x: tuple(x)).to_dict() 
df2['income'] = df2.apply(lambda x: np.random.choice(age_groups[x['agerange'],x['gender']]) if (x['agerange'],x['gender']) in age_groups else 0,axis=1) 

输出:

 
    agerange gender index income 
0   3  0  0 43000 
1   2  0  1 25600 
2   6  0  2  0 
3   4  0  3 106000 
3
d2['income'] = d2.apply(lambda x: d1.loc[(d1.agerange==x.agerange) &(d1.gender == x.gender),'income'].sample(n=1).max(),axis=1) 

输出:

index agerange gender income 
0  0   3  0  200 
1  1   2  0 25600 
2  2   4  0 3000 
3  3   4  0 106000