2017-10-11 2 views
3

En fait, mon problème est basé sur le:Comment faire pd.get_dummies ou d'autres moyens?

Is there a faster way to update dataframe column values based on conditions?

Ainsi, les données doivent être:

import pandas as pd 
import io 
t=""" 
AV4MdG6Ihowv-SKBN_nB DTP,FOOD 
AV4Mc2vNhowv-SKBN_Rn Cash 1,FOOD 
AV4MeisikOpWpLdepWy6 DTP,Bar 
AV4MeRh6howv-SKBOBOn Cash 1,FOOD 
AV4Mezwchowv-SKBOB_S DTOT,Bar 
AV4MeB7yhowv-SKBOA5b DTP,Bar 
""" 
data_vec=pd.read_csv(io.StringIO(t),sep='\s{2,}',names=['id','source']) 
data_vec 

C'est le data_vec:

id source 
0 AV4MdG6Ihowv-SKBN_nB DTP,FOOD 
1 AV4Mc2vNhowv-SKBN_Rn Cash 1,FOOD 
2 AV4MeisikOpWpLdepWy6 DTP,Bar 
3 AV4MeRh6howv-SKBOBOn Cash 1,FOOD 
4 AV4Mezwchowv-SKBOB_S DTOT,Bar 
5 AV4MeB7yhowv-SKBOA5b DTP,Bar 

Si je veux la résultat comme suit: (Cela signifie comment vectoriser les mutipletags ou les catégories?)

    _id source_Cash 1 source_DTOT source_DTP Food Bar 
0 AV4MdG6Ihowv-SKBN_nB    0   0  1  1 0 
1 AV4Mc2vNhowv-SKBN_Rn    1   0  0  1 0 
2 AV4MeisikOpWpLdepWy6    0   0  1  0 1 
3 AV4MeRh6howv-SKBOBOn    1   0  0  1 0 
4 AV4Mezwchowv-SKBOB_S    0   1  0  0 1 
5 AV4MeB7yhowv-SKBOA5b    0   0  1  0 1 

S'il s'agit d'un doublon, avertissez-moi de supprimer!

+1

probablement un double, mais je ne sais pas . de toute façon, 'get_dummies' prend un séparateur qui va traiter avec des valeurs multiples:' data_vec.source.str.get_dummies (sep = ',') ' – JohnE

+1

@JohnE Merci pour votre commentaire, j'ai appris quelque chose de nouveau! Je ne savais pas sur le séparateur. –

+0

Moi aussi! @JohnE @COLDSPEED – ileadall42

Répondre

5

Un peu de str.split et pd.get_dummies magie, inspired by Scott Boston et amélioré (à partir de la version originale) thanks to JohnE.

df = df.set_index('id').source.str.get_dummies(',') 
df.columns = df.columns.str.split().str[0].str.lower() 
df = df.add_prefix('source_').reset_index() 

print(df) 
        id source_bar source_cash source_dtot source_dtp \ 
0 AV4MdG6Ihowv-SKBN_nB   0   0   0   1 
1 AV4Mc2vNhowv-SKBN_Rn   0   1   0   0 
2 AV4MeisikOpWpLdepWy6   1   0   0   1 
3 AV4MeRh6howv-SKBOBOn   0   1   0   0 
4 AV4Mezwchowv-SKBOB_S   1   0   1   0 
5 AV4MeB7yhowv-SKBOA5b   1   0   0   1 

    source_food 
0   1 
1   1 
2   0 
3   1 
4   0 
5   0 
1

Vous pouvez aussi le faire: Ce que je fais est le fractionnement de la colonne « Source » et la création de nouveaux rows.Then j'appelle get_dummies sur la colonne source, GroupBy puis la colonne « id ».

data_vec = pd.DataFrame(pd.concat([pd.Series(row['id'], row['source'].split(','))    
        for _, row in data_vec.iterrows()])).reset_index() 
data_vec.columns = ['source','id'] 

qui donne:

source   id 
0 DTP  AV4MdG6Ihowv-SKBN_nB 
1 FOOD AV4MdG6Ihowv-SKBN_nB 
2 Cash 1 AV4Mc2vNhowv-SKBN_Rn 
3 FOOD AV4Mc2vNhowv-SKBN_Rn 
4 DTP  AV4MeisikOpWpLdepWy6 
5 Bar  AV4MeisikOpWpLdepWy6 
6 Cash 1 AV4MeRh6howv-SKBOBOn 
7 FOOD AV4MeRh6howv-SKBOBOn 
8 DTOT AV4Mezwchowv-SKBOB_S 
9 Bar  AV4Mezwchowv-SKBOB_S 
10 DTP  AV4MeB7yhowv-SKBOA5b 
11 Bar  AV4MeB7yhowv-SKBOA5b 

puis appelez get_dummies() sur la colonne source:

result = pd.concat([data_vec.get(['id']), 
          pd.get_dummies(data_vec['source'], prefix='source')],axis=1) 

result.groupby('id').sum().reset_index() 

Ce qui donne:

  id   source_Bar source_Cash 1 source_DTOT source_DTP source_FOOD 
0 AV4Mc2vNhowv-SKBN_Rn 0    1    0  0   1 
1 AV4MdG6Ihowv-SKBN_nB 0    0    0  1   1 
2 AV4MeB7yhowv-SKBOA5b 1    0    0  1   0 
3 AV4MeRh6howv-SKBOBOn 0    1    0  0   1 
4 AV4MeisikOpWpLdepWy6 1    0    0  1   0 
5 AV4Mezwchowv-SKBOB_S 1    0    1  0   0 
+0

Si vous allez de cette façon, vous pouvez simplement diviser sur virgule et pile. Cependant, [juste appeler 'pd.get_dummies' directement] (https://stackoverflow.com/a/46679500/4909087) sans faire tout cela serait beaucoup plus simple, ceci est inutilement compliqué. –

+0

Je suis d'accord.J'ai appris une nouvelle chose aujourd'hui que nous pourrions appeler get_dummies() en donnant une virgule. – Gayatri