Il y a une opération qui est un peu contre-intuitive quand on utilise la méthode apply() de pandas. Il m'a fallu quelques heures de lecture pour résoudre, alors voilà.À partir d'une base de données utilisant la méthode apply(), comment retourner une nouvelle colonne avec des listes d'éléments de la base de données?
Voici donc ce que j'essayais d'accomplir.
J'ai un dataframe de pandas géants comme ceci:
test = pd.DataFrame({'one': [[2],['test']], 'two': [[5],[10]]})
one two
0 [2] [5]
1 [test] [10]
et je veux ajouter les colonnes par ligne pour créer une liste résultante de longueur = à la longueur initiale du dataframe comme ceci:
def combine(row):
result = row['one'] + row['two']
return(result)
Lors de l'exécution à travers la trame de données en utilisant la méthode appliquer():
test.apply(lambda x: combine(x), axis=1)
one two
0 2 5
1 test 10
Quelle st Ce n'est pas tout à fait ce que nous voulions. Ce que nous voulons est:
result
0 [2, 5]
1 [test, 10]
EDIT
Je sais qu'il ya des solutions plus simples à cet exemple. Mais ceci est une abstraction d'un operation.Here beaucoup plus complexe est un exemple de plus complexe:
df_one:
org_id date status id
0 2 2015/02/01 True 3
1 10 2015/05/01 True 27
2 10 2015/06/01 True 18
3 10 2015/04/01 False 27
4 10 2015/03/01 True 40
df_two:
org_id date
0 12 2015/04/01
1 10 2015/02/01
2 2 2015/08/01
3 10 2015/08/01
Voilà une opération plus complexe:
def operation(row, df_one):
sel = (df_one.date < pd.Timestamp(row['date'])) & \
(df_one['org_id'] == row['org_id'])
last_changes = df_one[sel].groupby(['org_id', 'id']).last()
id_list = last_changes[last_changes.status].reset_index().id.tolist()
return (id_list)
puis finalement exécuter:
df_one.sort_values('date', inplace=True)
df_two['id_list'] = df_two.apply(
operation,
axis=1,
args=(df_one,)
)
Cela serait impossible avec des solutions plus simples. D'où ma proposition on pourrait être à nouveau ci-dessous écrire operation
à:
def operation(row, df_one):
sel = (df_one.date < pd.Timestamp(row['date'])) & \
(df_one['org_id'] == row['org_id'])
last_changes = df_one[sel].groupby(['org_id', 'id']).last()
id_list = last_changes[last_changes.status].reset_index().id.tolist()
return pd.Series({'id_list': id_list})
Nous attendrions le résultat suivant:
id_list
0 []
1 []
2 [3]
3 [27,18,40]
Quel est le type de vos colonnes de date dans vos deux dataframes? Par exemple. string, timestamp, etc. – Alexander
La dernière rangée ne devrait-elle pas être '[18, 27, 40]'? – Alexander
ou '[27, 18, 40]' puisque la ligne 1 dans 'df_one' semble satisfaire aux critères et vient avant la ligne 2. – Alexander