2017-07-31 12 views
5

Próbuję losowo przypisać wartości z jednej kolumny w jednej ramce danych, do innej ramki danych w 12 różnych kategoriach (według agerange i płci). Na przykład mam dwie ramki danych; Nazwijmy jedną D1 i D2 drugiJak przypisać wartości losowo między ramkami danych

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  

chcę grupy oba dataframes przez ZakresWieku i płci tj 0-1,2,3,4,5,6 & 1-1,2,3,4, 5,6 następnie losowo wybrał jeden z dochodów w ramach d1 i przypisać go do d2.

tj:

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 

Odpowiedz

4

Wariant 1
podejście z np.random.choice i pd.DataFrame.query
Podejmuję domyślne założenie, że zastępujemy losowo rysowane wartości dla każdego wiersza.

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 

Opcja 2
Próba uczynienia go bardziej wydajny zadzwonić np.random.choice raz na grupę.

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 

debugowanie i konfiguracja

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

Witam, Próbowałem swoje sugestie opcja 2 i dostałem błąd ** IndexingError: Zbyt wiele indeksujący ** prawda masz pojęcie, co może być przyczyną tego problemu? – stav

+0

@kstav Dodałem sekcję, w której można dokładnie skopiować i wkleić kod. Jeśli generuje pożądany wynik, problem dotyczy konkretnej ramki danych. Jeśli nadal występuje problem, problem musi dotyczyć wersji lub czegoś. – piRSquared

+0

kod, który wysłałeś, działa, zobaczę, co może być przyczyną problemu.Dzięki – stav

3

Jak o tworzeniu słownika dochodów na podstawie ageranges a następnie zmapować losowy wybór tj

#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])) 

wyjściowa:

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

Jeśli grupa płci wymagane również wtedy możesz użyć apply, jeśli chcesz wypełnić 0 dla kluczy, których nie możesz znaleźć, jeśli nie, to

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) 

wyjściowa:

 
    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) 

wyjściowa:

index agerange gender income 
0  0   3  0  200 
1  1   2  0 25600 
2  2   4  0 3000 
3  3   4  0 106000 
Powiązane problemy