Dodaj tablicę numpy jako kolumnę do ramki danych Pandas


85

Mam obiekt ramki danych Pandy w kształcie (X, Y), który wygląda następująco:

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

i numpy rzadkiej macierzy (CSC) w kształcie (X, Z), która wygląda mniej więcej tak

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

Jak mogę dodać zawartość z macierzy do ramki danych w nowej nazwanej kolumnie, tak aby ramka danych zakończyła się następująco:

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

Zauważ, że ramka danych ma teraz kształt (X, Y + 1), a wiersze z macierzy są elementami w ramce danych.


2
Ten rodzaj zagnieżdżania jest odradzany. Dlaczego musisz to zrobić?
Phillip Cloud,


Chcę zachować możliwość zaznaczenia poprzedniej zawartości macierzy po jednej nazwie kolumny po scaleniu.
Mihai Damian,

Dlaczego po prostu nie użyjesz dwóch DataFrame?
Phillip Cloud,

Odpowiedzi:


81
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)

plony

   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]

6
Myślę, że tak naprawdę nie możemy zapewnić kuloodpornych butów użytkownikom, którzy nalegają na robienie takich rzeczy: /
Phillip Cloud

6
Jest wiele interesujących rzeczy, które możesz zrobić z kolumną list , więc wolałbym nie zakładać, że to koniecznie zły pomysł. Chociaż zgadzam się, jest duża szansa, że ​​tak jest.
unutbu

1
To wspaniały przykład pandaselastyczności. W przypadku tego pytania dane są już jednorodnym typem liczbowym z równymi rzędami, podczas gdy w tym przykładzie są to listróżne długości. Zgadzam się, że możesz zrobić ciekawe rzeczy. Jeśli jednak masz już macierz, po co zamieniać ją w listę list?
Phillip Cloud,

1
„Ciekawą rzeczą” jest… sprawienie, że nie jest to już kolumna list (więc jest przydatna)!
Andy Hayden,

54
Świat jest lepszym miejscem, w którym kreatywnym ludziom wolno robić rzeczy, które wszyscy uważają za głupie. :)
unutbu

10

Rozważ użycie bardziej wymiarowej struktury danych ( panel ) zamiast przechowywania tablicy w kolumnie:

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

Spójrz na przekroje itp. Itd.

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

Zobacz dokumentację, aby uzyskać więcej informacji na temat paneli .


12
Panel został wycofany
guhur

Tak, obecnie zwykle zaleca się MultiIndex. Utworzony np pd.concat([df, csc], axis=1, keys=["df", "csc"]). Przez .
Andy Hayden

A = np.eye(3); df = pd.concat( [A,A], axis=1 )-> TypeError: nie można połączyć obiektu innego niż NDFrame w 20.2? (Przydałaby się wiki „pandas-deprecated-now-use-this”).
denis

@denis tryA = pd.DataFrame(np.eye(3)); df = pd.concat( [A,A], axis=1, keys=["A", "B"] )
Andy Hayden

Dzięki, df.columns MultiIndex(levels=[[u'A', u'B'], [0, 1, 2]](uderza w czoło)
denis,

3

Oto inny przykład:

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'])

Zasadniczym sekretem jest przydzielenie danych w postaci a = [(tablica_11, tablica_12, ..., tablica_1n), ..., (tablica_m1, tablica_m2, ..., tablica_mn)], a panda DataFrame uporządkuje dane w n kolumnach tablic. Oczywiście zamiast tokenów można by użyć tablic tablic, w takim przypadku forma byłaby następująca: a = [[tablica_11, tablica_12, ..., tablica_1n], ..., [tablica_m1, tablica_m2, ..., tablica_mn ]]

To jest wynik, jeśli drukujesz (df) z powyższego kodu:

                       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]

Inne odmiany powyższego przykładu:

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'])

Wyjście 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]

Jeśli chcesz dodać inne kolumny tablic, to:

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])]

Ostateczny wynik df będzie:

   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]

1

Możesz dodać i pobrać tablicę numpy z dataframe za pomocą tego:

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

Opiera się to na poprzedniej odpowiedzi, która zdezorientowała mnie z powodu rzadkiej części, a to działa dobrze w przypadku nie rzadkich, numpy arrray.


0
df = pd.DataFrame(np.arange(1,10).reshape(3,3))
df['newcol'] = pd.Series(your_2d_numpy_array)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.