Tworzenie ramki danych Pandas z tablicy Numpy: Jak określić kolumnę indeksu i nagłówki kolumn?

281

Mam tablicę Numpy składającą się z listy list reprezentujących dwuwymiarową tablicę z etykietami wierszy i nazwami kolumn, jak pokazano poniżej:

data = array([['','Col1','Col2'],['Row1',1,2],['Row2',3,4]])

Chciałbym, aby wynikowa DataFrame miała Row1 i Row2 jako wartości indeksu, a Col1, Col2 jako wartości nagłówka

Mogę określić indeks w następujący sposób:

df = pd.DataFrame(data,index=data[:,0]),

nie jestem jednak pewien, jak najlepiej przypisać nagłówki kolumn.

użytkownik3132783
źródło
3
Odpowiedź @ behzad.nouri jest prawidłowa, ale myślę, że powinieneś rozważyć, czy nie możesz mieć danych początkowych w innej formie. Ponieważ teraz twoje wartości będą ciągami, a nie liczbami całkowitymi (ze względu na mieszanie tablic liczb całkowitych liczb całkowitych i łańcuchów, więc wszystkie są rzutowane na łańcuch, ponieważ tablice liczb liczbowych muszą być jednorodne).
joris

Odpowiedzi:

315

Trzeba określić data, indexi columnsdo DataFramekonstruktora, na przykład:

>>> pd.DataFrame(data=data[1:,1:],    # values
...              index=data[1:,0],    # 1st column as index
...              columns=data[0,1:])  # 1st row as the column names

edycja : jak w komentarzu @joris, może być konieczna zmiana powyżej, np.int_(data[1:,1:])aby mieć poprawny typ danych.

behzad.nouri
źródło
7
to działa - ale czy w przypadku takiej wspólnej struktury danych wejściowych i pożądanej aplikacji DataFramenie ma jakiegoś „skrótu”? Jest to w zasadzie sposób, w jaki csvsą ładowane - i mogą być zarządzane przez domyślną obsługę wielu czytników csv. Przydałaby się analogiczna struktura dla plików df.
javadba
Jako dodatkową odpowiedź dodałem metodę mini pomocnika / wygody.
javadba
93

Oto łatwe do zrozumienia rozwiązanie

import numpy as np
import pandas as pd

# Creating a 2 dimensional numpy array
>>> data = np.array([[5.8, 2.8], [6.0, 2.2]])
>>> print(data)
>>> data
array([[5.8, 2.8],
       [6. , 2.2]])

# Creating pandas dataframe from numpy array
>>> dataset = pd.DataFrame({'Column1': data[:, 0], 'Column2': data[:, 1]})
>>> print(dataset)
   Column1  Column2
0      5.8      2.8
1      6.0      2.2
Jagannath Banerjee
źródło
20
Ale trzeba było ręcznie określić Seriesnazwy ... to nie jest skalowalne.
javadba
24

Zgadzam się z Jorisem; wygląda na to, że powinieneś robić to inaczej, jak w przypadku wielu tablic rekordów . Modyfikując „opcję 2” z tej świetnej odpowiedzi , możesz to zrobić w następujący sposób:

import pandas
import numpy

dtype = [('Col1','int32'), ('Col2','float32'), ('Col3','float32')]
values = numpy.zeros(20, dtype=dtype)
index = ['Row'+str(i) for i in range(1, len(values)+1)]

df = pandas.DataFrame(values, index=index)
ryanjdillon
źródło
13

Można to zrobić po prostu używając from_records z pand DataFrame

import numpy as np
import pandas as pd
# Creating a numpy array
x = np.arange(1,10,1).reshape(-1,1)
dataframe = pd.DataFrame.from_records(x)
Aadil Srivastava
źródło
Ta odpowiedź nie działa z przykładowymi danymi podanymi w pytaniu, tj data = array([['','Col1','Col2'],['Row1',1,2],['Row2',3,4]]).
JPP
Najprostsze ogólne rozwiązanie, gdy nie określono etykiet.
cerebrou
12
    >>import pandas as pd
    >>import numpy as np
    >>data.shape
    (480,193)
    >>type(data)
    numpy.ndarray
    >>df=pd.DataFrame(data=data[0:,0:],
    ...        index=[i for i in range(data.shape[0])],
    ...        columns=['f'+str(i) for i in range(data.shape[1])])
    >>df.head()
    [![array to dataframe][1]][1]

wprowadź opis zdjęcia tutaj

Rahul Verma
źródło
8

Dodając do odpowiedzi @ behzad.nouri - możemy stworzyć procedurę pomocniczą do obsługi tego typowego scenariusza:

def csvDf(dat,**kwargs): 
  from numpy import array
  data = array(dat)
  if data is None or len(data)==0 or len(data[0])==0:
    return None
  else:
    return pd.DataFrame(data[1:,1:],index=data[1:,0],columns=data[0,1:],**kwargs)

Wypróbujmy to:

data = [['','a','b','c'],['row1','row1cola','row1colb','row1colc'],
     ['row2','row2cola','row2colb','row2colc'],['row3','row3cola','row3colb','row3colc']]
csvDf(data)

In [61]: csvDf(data)
Out[61]:
             a         b         c
row1  row1cola  row1colb  row1colc
row2  row2cola  row2colb  row2colc
row3  row3cola  row3colb  row3colc
javadba
źródło