2
votes

comment soustraire tous les éléments du dataframe pandas les uns avec les autres plus facilement?

disons que j'ai un dataframe comme celui-ci

    name1 name2 time_diff
    a     a      0
    a     b     -20
    a     c     -1
    a     d     -3
    b     a      20
    b     b      0
    b     c      19
    b     d      17
    .....
    .....
    d     d      0

maintenant je veux un nouveau dataframe comme celui-ci

name time
a    10
b    30
c    11
d    13

imbriqué pour les boucles, lambda La fonction peut être utilisée mais comme le nombre d'éléments dépasse 200, les boucles for prennent trop de temps à se terminer ou devrais-je dire, je dois toujours interrompre le processus. Est-ce que quelqu'un connaît un moyen de requête de panda ou quelque chose de plus rapide et plus facile. la forme de mon dataframe est 1600x2


0 commentaires

3 Réponses :


3
votes

Utilisez d'abord la jointure croisée en merge avec la colonne d'aide, obtenez la différence et sélectionnez uniquement les colonnes nécessaires:

df = df.set_index('name')
mux = pd.MultiIndex.from_product([df.index, df.index], names=['name1','name2'])

df = (df['time'].reindex(mux, level=0)
        .sub(df.reindex(mux, level=1)['time'])
        .rename('time_diff')
        .reset_index())

Une autre solution avec MultiIndex.from_product et reindex par premier et deuxième niveau:

df = df.assign(A=1)
df = pd.merge(df, df, on='A', suffixes=('1','2'))
df['time_diff'] = df['time1'] - df['time2']
df = df[['name1','name2','time_diff']]
print (df)
   name1 name2  time_diff
0      a     a          0
1      a     b        -20
2      a     c         -1
3      a     d         -3
4      b     a         20
5      b     b          0
6      b     c         19
7      b     d         17
8      c     a          1
9      c     b        -19
10     c     c          0
11     c     d         -2
12     d     a          3
13     d     b        -17
14     d     c          2
15     d     d          0


0 commentaires

3
votes

Solution avec itertools:

import itertools
d=pd.DataFrame(list(itertools.product(df.name,df.name)),columns=['name1','name2'])
dic = dict(zip(df.name,df.time))
d['time_diff']=d.name1.map(dic)-d.name2.map(dic)
print(d)
   name1 name2  time_diff
0      a     a          0
1      a     b        -20
2      a     c         -1
3      a     d         -3
4      b     a         20
5      b     b          0
6      b     c         19
7      b     d         17
8      c     a          1
9      c     b        -19
10     c     c          0
11     c     d         -2
12     d     a          3
13     d     b        -17
14     d     c          2
15     d     d          0


1 commentaires

à mesure que le nombre de lignes augmente, il génère maintenant une erreur de mémoire.



1
votes

une autre façon serait, df.apply

   name1 name2  time_diff
0      a     a          0
1      a     b        -20
2      a     c         -1
3      a     d         -3
4      b     a         20
5      b     b          0
6      b     c         19
7      b     d         17
8      c     a          1
9      c     b        -19
10     c     c          0
11     c     d         -2
12     d     a          3
13     d     b        -17
14     d     c          2
15     d     d          0

O/P:

df=pd.DataFrame({'col':['a','b','c','d'],'col1':[10,30,11,13]})
index = pd.MultiIndex.from_product([df['col'], df['col']], names = ["name1", "name2"])
res=pd.DataFrame(index = index).reset_index()
res['time_diff']=df.apply(lambda x: x['col1']-df['col1'],axis=1).values.flatten()


0 commentaires