Dies ist ein minimales Beispiel für das Problem:

import pandas as pd
example = pd.DataFrame(index=pd.np.arange(2) , columns=['A', 'B', 'C']).astype('object')
example.loc[0] = [['a'], 'b', [1,2,3]]
example.loc[1] = ['a', 'b', [1,2,3]]

Ich bekomme ein ValueError: setting an array element with a sequence

So sieht der DataFrame in Spyder aus: Bildbeschreibung hier eingeben

Ich verstehe nicht, warum das erste Element "verschachtelt" sein muss. Warum funktioniert die zweite Reihe nicht? Was mache ich falsch? Bitte schauen Sie sich die zweite Spalte an, in der 'b' direkt eingefügt werden kann.


Ich habe für die Antwort gestimmt, die mir persönlich am besten gefällt, von allen drei Arbeitslösungen, die freundlicherweise zur Verfügung gestellt wurden. Ich finde es etwas pythonischer als die anderen Antworten und außerdem ist es auch das schnellste . Einen Geschwindigkeitsvergleich finden Sie in diesem Beitrag unter

3
TimK 18 Apr. 2018 im 16:21

4 Antworten

Beste Antwort

Sie stoßen an die Grenzen der Pandas. Es ist nicht gut im Umgang mit Objekten höherer Ebenen. Also müssen wir vorsichtig sein.

In Ihrem Fall sieht Pandas nicht sofort, dass es sich um ein Array von Objekten handelt, und schlägt fehl, wenn die Sequenz erreicht wird.

Umgehen

Eingewickelt in ein Serienobjekt

import pandas as pd
example = pd.DataFrame(index=pd.np.arange(2) , columns=['A', 'B', 'C']).astype('object')
example.loc[0] = [['a'], 'b', [1,2,3]]
example.loc[1] = pd.Series(['a', 'b', [1,2,3]], example.columns)

example

     A  B          C
0  [a]  b  [1, 2, 3]
1    a  b  [1, 2, 3]
3
piRSquared 18 Apr. 2018 im 13:28

Pandas funktionieren nicht gut mit nicht skalaren Daten, die meisten Funktionen von Pandas und Numpy wären unerreichbar. Eine Lösung für Ihr Problem besteht darin, die Verwendung von Arrays in loc und die explizite Indizierung von Zellen zu vermeiden.

example.loc[1, “C”] = [1, 2, 3] #This works

for val, col in zip(['a', 'b', [1,2,3]], example.columns):
    example.loc[1, col] = val
1
iDrwish 20 Apr. 2018 im 12:15

Pandas ist nicht dafür ausgelegt, Sammlungen als Elemente von Serien zu speichern.

Dies zeigt sich nicht nur in Ihrer spezifischen Aufgabe, sondern auch in andere pandas Funktionen ebenfalls. Manchmal ist es ein Fehler, manchmal eine unbeabsichtigte Konsequenz, manchmal beabsichtigt.

Eine alternative Methode funktioniert, wenn Sie Ihren Index nicht vorher festlegen:

import pandas as pd

example = pd.DataFrame(columns=['A', 'B', 'C']).astype('object')

example.loc[0] = [['a'], 'b', [1,2,3]]
example.loc[1] = ['a', 'b', [1,2,3]]

print(example)

#      A  B          C
# 0  [a]  b  [1, 2, 3]
# 1    a  b  [1, 2, 3]
3
jpp 20 Apr. 2018 im 12:23

Alle drei Antworten funktionieren! Aber welches ist das schnellste?

Alle drei bereitgestellten Lösungen von piRSquared, > jpp, iDrwish funktionieren

In meinen Fragen habe ich nicht nach einer schnellen Lösung gefragt. Daher beantworte ich diesen zusätzlichen Teil der Frage nur mit einem zeitlichen Vergleich aller drei Optionen. Das Ergebnis des Vergleichs (Code unten) ist:

Result piRSquared(): 37.966
Result jpp(): 114.580
Result iDrwish(): 154.336

Der Arbeitscode für den Test lautet:

import pandas as pd
import timeit

rows=5000

def iDrwish():
    example1 = pd.DataFrame(index = pd.np.arange(rows), columns=['A', 'B', 'C']).astype('object')
    for row in range(rows):
        for val, col in zip(['a', 'b', [1,2,3]], example1.columns):
            example1.loc[rows, col] = val


def jpp():
    example2 = pd.DataFrame(columns=['A', 'B', 'C']).astype('object')
    for row in range(rows):
        example2.loc[row] = ['a', 'b', [1,2,3]]


def piRSquared():
    example3 = pd.DataFrame(index = pd.np.arange(rows), columns=['A', 'B', 'C']).astype('object')
    for row in range(rows):
        example3.loc[row] = pd.Series(['a', 'b', [1,2,3]])        


if __name__ == '__main__':
    print('Result piRSquared(): ' + str(timeit.timeit(piRSquared, number = 11)))
    print('Result jpp(): ' + str(timeit.timeit(jpp, number = 11)))
    print('Result iDrwish(): ' + str(timeit.timeit(iDrwish, number = 11)))
0
TimK 20 Apr. 2018 im 13:51