web-dev-qa-db-fra.com

Pandon Python insérer la liste dans une cellule

J'ai une liste 'abc' et un dataframe 'df':

abc = ['foo', 'bar']
df =
    A  B
0  12  NaN
1  23  NaN

Je veux insérer la liste dans la cellule 1B, je veux donc ce résultat:

    A  B
0  12  NaN
1  23  ['foo', 'bar']

Ho puis-je faire ça?

1) Si j'utilise ceci:

df.ix[1,'B'] = abc

Je reçois le message d'erreur suivant:

ValueError: Must have equal len keys and value when setting with an iterable

parce qu'il essaie d'insérer la liste (qui a deux éléments) dans une ligne/colonne mais pas dans une cellule.

2) Si j'utilise ceci:

df.ix[1,'B'] = [abc]

puis il insère une liste qui ne contient qu'un élément, la liste 'abc' ([['foo', 'bar']]).

3) Si j'utilise ceci:

df.ix[1,'B'] = ', '.join(abc)

alors il insère une chaîne: (foo, bar) mais pas une liste.

4) Si j'utilise ceci:

df.ix[1,'B'] = [', '.join(abc)]

alors il insère une liste mais il n’a qu’un élément (['foo, bar']) mais pas deux comme je le souhaite (['foo', 'bar']).

Merci pour l'aide!


MODIFIER

Mon nouveau dataframe et l'ancienne liste:

abc = ['foo', 'bar']
df2 =
    A    B         C
0  12  NaN      'bla'
1  23  NaN  'bla bla'

Un autre dataframe:

df3 =
    A    B         C                    D
0  12  NaN      'bla'  ['item1', 'item2']
1  23  NaN  'bla bla'        [11, 12, 13]

Je veux insérer la liste 'abc' dans df2.loc[1,'B'] et/ou df3.loc[1,'B'].

Si la structure de données contient uniquement des colonnes avec des valeurs entières et/ou des valeurs NaN et/ou des valeurs de liste, l'insertion d'une liste dans une cellule fonctionne parfaitement. Si la structure de données contient uniquement des colonnes avec des valeurs de chaîne et/ou des valeurs NaN et/ou des valeurs de liste, l'insertion d'une liste dans une cellule fonctionne parfaitement. Mais si le cadre de données a des colonnes avec des valeurs de nombre entier et chaîne et d'autres colonnes, le message d'erreur s'affiche si j'utilise ceci: df2.loc[1,'B'] = abc ou df3.loc[1,'B'] = abc.

Un autre dataframe:

df4 =
          A     B
0      'bla'  NaN
1  'bla bla'  NaN

Ces inserts fonctionnent parfaitement: df.loc[1,'B'] = abc ou df4.loc[1,'B'] = abc.

57
ragesz

df3.set_value(1, 'B', abc) fonctionne pour toute base de données. Prenez soin du type de données de la colonne 'B'. Par exemple. une liste ne peut pas être insérée dans une colonne flottante, df['B'] = df['B'].astype(object) peut alors aider.

34
ragesz

Mise à jour 2017

Depuis que set_value est obsolète depuis la version 0.21.0, vous devez maintenant utiliser at . Il peut insérer une liste dans une cellule sans générer une ValueError comme le fait loc. Je pense que cela est dû au fait que atalways fait référence à une valeur unique, alors que loc peut désigner des valeurs ainsi que des lignes et des colonnes.

df = pd.DataFrame(data={'A': [1, 2, 3], 'B': ['x', 'y', 'z']})

df.at[1, 'B'] = ['m', 'n']

df =
    A   B
0   1   x
1   2   [m, n]
2   3   z
64
Michael Hays

Comme mentionné dans cet article pandas: comment stocker une liste dans une base de données? ; obtenir des types dans le cadre de données peut influer sur les résultats, ainsi que d'appeler ou non un cadre de données.

2
Ando Jurai

v0.23 +, set_value est obsolète.
Vous pouvez maintenant utiliser DataFrame.at pour définir par étiquette et DataFrame.iat pour définir par position entière.


Définition des valeurs de cellule avec at / iat

# Setup
df = pd.DataFrame({'A': [12, 23], 'B': [['a', 'b'], ['c', 'd']]})
df

    A       B
0  12  [a, b]
1  23  [c, d]

df.dtypes

A     int64
B    object
dtype: object

Si vous voulez définir une valeur dans la deuxième ligne du "B" pour une nouvelle liste, utilisez DataFrane.at:

df.at[1, 'B'] = ['m', 'n']
df

    A       B
0  12  [a, b]
1  23  [m, n]

Vous pouvez également définir par position entière en utilisant DataFrame.iat

df.iat[1, df.columns.get_loc('B')] = ['m', 'n']
df

    A       B
0  12  [a, b]
1  23  [m, n]

Et si je reçois ValueError: setting an array element with a sequence?

Je vais essayer de reproduire ceci avec:

df

    A   B
0  12 NaN
1  23 NaN

df.dtypes

A      int64
B    float64
dtype: object

df.at[1, 'B'] = ['m', 'n']
# ValueError: setting an array element with a sequence.

Cela est dû au fait que votre objet est de type float64 d, alors que les listes sont de type objects, il y a donc une différence. Dans ce cas, vous devez d'abord convertir la colonne en objet.

df['B'] = df['B'].astype(object)
df.dtypes

A     int64
B    object
dtype: object

Ensuite, ça marche:

df.at[1, 'B'] = ['m', 'n']
df

    A       B
0  12     NaN
1  23  [m, n]

Possible, mais Hacky

Encore plus farfelu, j'ai trouvé que vous pouvez pirater DataFrame.loc pour obtenir quelque chose de similaire si vous passez des listes imbriquées.

df.loc[1, 'B'] = [['m'], ['n'], ['o'], ['p']]
df

    A             B
0  12        [a, b]
1  23  [m, n, o, p]
2
coldspeed

Travail rapide

Insérez simplement la liste dans une nouvelle liste, comme pour col2 dans le bloc de données ci-dessous. Cela fonctionne parce que python prend la liste externe (des listes) et la convertit en une colonne comme si elle contenait des éléments scalaires normaux, qui sont des listes dans notre cas et non des scalaires normaux.

mydict={'col1':[1,2,3],'col2':[[1, 4], [2, 5], [3, 6]]}
data=pd.DataFrame(mydict)
data


   col1     col2
0   1       [1, 4]
1   2       [2, 5]
2   3       [3, 6]
0
Pallavi Jindal