Fügen Sie dem Pandas-Datenrahmen ein numpy-Array als Spalte hinzu

82

Ich habe ein Pandas-Datenrahmenobjekt mit der Form (X, Y), das folgendermaßen aussieht:

[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]

und eine numpy sparse Matrix (CSC) der Form (X, Z), die ungefähr so ​​aussieht

[[0, 1, 0],
[0, 0, 1],
[1, 0, 0]]

Wie kann ich den Inhalt aus der Matrix zum Datenrahmen in einer neuen benannten Spalte hinzufügen, sodass der Datenrahmen wie folgt endet:

[[1, 2, 3, [0, 1, 0]],
[4, 5, 6, [0, 0, 1]],
[7, 8, 9, [1, 0, 0]]]

Beachten Sie, dass der Datenrahmen jetzt die Form (X, Y + 1) hat und Zeilen aus der Matrix Elemente im Datenrahmen sind.

Mihai Damian
quelle
2
Von dieser Art der Verschachtelung wird abgeraten. Warum müssen Sie das tun?
Phillip Cloud
Siehe diese Frage: stackoverflow.com/q/18641148/564538
Phillip Cloud
Ich möchte die Möglichkeit behalten, den vorherigen Inhalt der Matrix nach dem Zusammenführen durch einen einzelnen Spaltennamen auszuwählen.
Mihai Damian
Warum benutzt du nicht einfach zwei DataFrame?
Phillip Cloud

Antworten:

78
import numpy as np
import pandas as pd
import scipy.sparse as sparse

df = pd.DataFrame(np.arange(1,10).reshape(3,3))
arr = sparse.coo_matrix(([1,1,1], ([0,1,2], [1,2,0])), shape=(3,3))
df['newcol'] = arr.toarray().tolist()
print(df)

ergibt

   0  1  2     newcol
0  1  2  3  [0, 1, 0]
1  4  5  6  [0, 0, 1]
2  7  8  9  [1, 0, 0]
unutbu
quelle
6
Ich denke, wir können Benutzern, die darauf bestehen, solche Dinge zu tun, keine wirklich kugelsicheren Schuhe anbieten: /
Phillip Cloud
6
Es gibt interessante Dinge, die Sie mit einer Listenspalte tun können , daher würde ich lieber nicht davon ausgehen, dass dies notwendigerweise eine schlechte Idee ist. Obwohl ich damit einverstanden bin, besteht eine hohe Wahrscheinlichkeit, dass dies der Fall ist.
Unutbu
1
Das ist ein wunderbares Beispiel für pandasFlexibilität. Bei dieser Frage sind die Daten bereits vom homogenen numerischen Typ mit gleich geformten Zeilen, während sie in diesem Beispiel listunterschiedlich lang sind. Ich bin damit einverstanden, dass Sie interessante Dinge tun können. Wenn Sie jedoch bereits eine Matrix haben, warum sollten Sie diese in eine Liste von Listen umwandeln?
Phillip Cloud
1
Das "Interessante" daran ist, dass es keine Listenspalte mehr ist (also nützlich)!
Andy Hayden
51
Die Welt ist ein besserer Ort, wenn kreative Menschen Dinge tun dürfen, die alle anderen für dumm halten. :)
Unutbu
10

Erwägen Sie die Verwendung einer höherdimensionalen Datenstruktur (a Panel ), anstatt ein Array in Ihrer Spalte zu speichern:

In [11]: p = pd.Panel({'df': df, 'csc': csc})

In [12]: p.df
Out[12]: 
   0  1  2
0  1  2  3
1  4  5  6
2  7  8  9

In [13]: p.csc
Out[13]: 
   0  1  2
0  0  1  0
1  0  0  1
2  1  0  0

Schauen Sie sich die Querschnitte usw. usw. usw. an.

In [14]: p.xs(0)
Out[14]: 
   csc  df
0    0   1
1    1   2
2    0   3

Weitere Informationen zu Panels finden Sie in den Dokumenten .

Andy Hayden
quelle
11
Panel ist jetzt veraltet
guhur
Ja, normalerweise wird heutzutage MultiIndex empfohlen. Erstellt zB über pd.concat([df, csc], axis=1, keys=["df", "csc"]).
Andy Hayden
A = np.eye(3); df = pd.concat( [A,A], axis=1 )-> TypeError: Kann ein Nicht-NDFrame-Objekt in 20.2 nicht verkettet werden? (Ein Wiki von "Pandas-veraltet-jetzt-benutze-dies" wäre schön.)
Denis
@denis versuchenA = pd.DataFrame(np.eye(3)); df = pd.concat( [A,A], axis=1, keys=["A", "B"] )
Andy Hayden
Danke, df.columns MultiIndex(levels=[[u'A', u'B'], [0, 1, 2]](schlägt auf die Stirn)
Denis
3

Hier ist ein anderes Beispiel:

import numpy as np
import pandas as pd

""" This just creates a list of touples, and each element of the touple is an array"""
a = [ (np.random.randint(1,10,10), np.array([0,1,2,3,4,5,6,7,8,9]))  for i in 
range(0,10) ]

""" Panda DataFrame will allocate each of the arrays , contained as a touple 
element , as column"""
df = pd.DataFrame(data =a,columns=['random_num','sequential_num'])

Das Geheimnis im Allgemeinen besteht darin, die Daten in der Form a = [(array_11, array_12, ..., array_1n), ..., (array_m1, array_m2, ..., array_mn)] zuzuweisen, und panda DataFrame ordnet die Daten an in n Spalten von Arrays. Natürlich könnten Arrays von Arrays anstelle von Touples verwendet werden. In diesem Fall wäre die Form: a = [[array_11, array_12, ..., array_1n], ..., [array_m1, array_m2, ..., array_mn ]]

Dies ist die Ausgabe, wenn Sie (df) aus dem obigen Code drucken:

                       random_num                  sequential_num
0  [7, 9, 2, 2, 5, 3, 5, 3, 1, 4]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1  [8, 7, 9, 8, 1, 2, 2, 6, 6, 3]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2  [3, 4, 1, 2, 2, 1, 4, 2, 6, 1]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
3  [3, 1, 1, 1, 6, 2, 8, 6, 7, 9]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
4  [4, 2, 8, 5, 4, 1, 2, 2, 3, 3]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
5  [3, 2, 7, 4, 1, 5, 1, 4, 6, 3]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
6  [5, 7, 3, 9, 7, 8, 4, 1, 3, 1]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
7  [7, 4, 7, 6, 2, 6, 3, 2, 5, 6]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
8  [3, 1, 6, 3, 2, 1, 5, 2, 2, 9]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
9  [7, 2, 3, 9, 5, 5, 8, 6, 9, 8]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Andere Variation des obigen Beispiels:

b = [ (i,"text",[14, 5,], np.array([0,1,2,3,4,5,6,7,8,9]))  for i in 
range(0,10) ]
df = pd.DataFrame(data=b,columns=['Number','Text','2Elemnt_array','10Element_array'])

Ausgabe von df:

   Number  Text 2Elemnt_array                 10Element_array
0       0  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1       1  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2       2  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
3       3  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
4       4  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
5       5  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
6       6  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
7       7  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
8       8  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
9       9  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Wenn Sie weitere Spalten von Arrays hinzufügen möchten, gehen Sie wie folgt vor:

df['3Element_array']=[([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3])]

Die endgültige Ausgabe von df ist:

   Number  Text 2Elemnt_array                 10Element_array 3Element_array
0       0  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
1       1  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
2       2  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
3       3  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
4       4  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
5       5  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
6       6  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
7       7  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
8       8  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
9       9  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
Jorge Vilchis
quelle
0

Bei normalen Numpy-Arrays können Sie dies zum Hinzufügen und Abrufen von Datenrahmen tun. Es baut auf der vorherigen Antwort auf, die mich wegen des spärlichen Teils verwirrte, als ich gerade ein normales Numpy-Array hatte.

import numpy as np
import pandas as pd

df = pd.DataFrame({'b':range(10)}) # target dataframe
a = np.random.normal(size=(10,2)) # numpy array
df['a']=a.tolist() # save array
np.array(df['a'].tolist()) # retrieve array
Stadtmensch
quelle
0
df = pd.DataFrame(np.arange(1,10).reshape(3,3))
df['newcol'] = pd.Series(your_2d_numpy_array)
Max Bileschi
quelle