2017-07-31 70 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