2013-06-13 23 views
67

Łatwe zadanie polegające na dodaniu wiersza do obiektu pandas.DataFrame wydaje się trudne. Istnieją 3 pytania dotyczące stackoverflow związane z tym, z których żaden nie daje działającej odpowiedzi.Pandy Pythona: wypełnij rząd ramki danych wierszem

Oto, co próbuję zrobić. Mam DataFrame, którego znam już kształt, jak również nazwy wierszy i kolumn.

>>> df = pandas.DataFrame(columns=['a','b','c','d'], index=['x','y','z']) 
>>> df 
    a b c d 
x NaN NaN NaN NaN 
y NaN NaN NaN NaN 
z NaN NaN NaN NaN 

Teraz mam funkcję do obliczania wartości wierszy iteracyjnie. Jak mogę wypełnić jeden z wierszy słownikiem lub pandas.Series? Oto różne próby, które się nie powiodły:

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df['y'] = y 
AssertionError: Length of values does not match length of index 

Najwyraźniej próbował dodać kolumnę zamiast wiersza.

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.join(y) 
AttributeError: 'builtin_function_or_method' object has no attribute 'is_unique' 

Bardzo nieinformacyjny komunikat o błędzie.

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.set_value(index='y', value=y) 
TypeError: set_value() takes exactly 4 arguments (3 given) 

Najwyraźniej jest to tylko ustawienie indywidualnych wartości w ramce danych.

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.append(y) 
Exception: Can only append a Series if ignore_index=True 

Cóż, nie chcę, aby zignorować indeksu, inaczej oto wynik:

>>> df.append(y, ignore_index=True) 
    a b c d 
0 NaN NaN NaN NaN 
1 NaN NaN NaN NaN 
2 NaN NaN NaN NaN 
3 1 5 2 3 

To nie wyrównać nazwy kolumn z wartościami, ale stracił etykiety wierszy.

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.ix['y'] = y 
>>> df 
            a         b \ 
x        NaN        NaN 
y {'a': 1, 'c': 2, 'b': 5, 'd': 3} {'a': 1, 'c': 2, 'b': 5, 'd': 3} 
z        NaN        NaN 

            c         d 
x        NaN        NaN 
y {'a': 1, 'c': 2, 'b': 5, 'd': 3} {'a': 1, 'c': 2, 'b': 5, 'd': 3} 
z        NaN        NaN 

To również zakończyło się nieszczęśliwie.

Jak to zrobić?

Odpowiedz

53

df['y'] ustawi kolumnę

ponieważ chcesz ustawić wiersz, należy .loc

Zauważ, że .ix odpowiada tu swoje powiodła się, ponieważ próbowano przypisać słownika do każdego elementu rzędu y prawdopodobnie nie to, co chcesz; konwersja do serialu opowiada pandy które chcesz wyrównać wejście (na przykład wtedy nie trzeba określić wszystkie elementy)

In [7]: df = pandas.DataFrame(columns=['a','b','c','d'], index=['x','y','z']) 

In [8]: df.loc['y'] = pandas.Series({'a':1, 'b':5, 'c':2, 'd':3}) 

In [9]: df 
Out[9]: 
    a b c d 
x NaN NaN NaN NaN 
y 1 5 2 3 
z NaN NaN NaN NaN 
+0

widzę. Tak więc atrybut 'loc' ramki danych definiuje specjalne' __setitem__', które robi magię, jak przypuszczam. – xApple

+0

Czy można skonstruować to w jednym przebiegu (np. Z kolumnami, indeksem i y)? –

+3

Więc jeśli mogę wygenerować jeden wiersz na raz, w jaki sposób mogę optymalnie zbudować ramkę danych? – xApple

10

To jest prostszą wersją

df = DataFrame(columns=('col1', 'col2', 'col3')) 
for i in range(5): 
    df.loc[i] = ['<some value for first>','<some value for second>','<some value for third>']` 
+2

Chcę tylko zapytać, czy ten procesor i pamięć są wydajne? – czxttkl

+1

Skąd mogę znać ostatni rząd DF, więc za każdym razem dołączam do ostatniego wiersza? – pashute

21

Moje podejście było, ale nie mogę zagwarantować, że jest to najszybsze rozwiązanie.

df = pd.Dataframe(columns=["firstname", "lastname"]) 
df = df.append({ 
    "firstname": "John", 
    "lastname": "Johny" 
     }, ignore_index=True) 
+2

To działało znakomicie dla mnie i podoba mi się fakt, że wyraźnie "dołączasz" dane do ramki danych. –

+0

Należy pamiętać, że ta odpowiedź wymaga, aby każdy wiersz zawierał nazwę kolumny. To samo dotyczy zaakceptowanej odpowiedzi. – pashute

3

Jeśli twoje wiersze wejściowe są listy zamiast słowniki, a następnie po to proste rozwiązanie:

import pandas as pd 
list_of_lists = [] 
list_of_lists.append([1,2,3]) 
list_of_lists.append([4,5,6]) 

pd.DataFrame(list_of_lists, columns=['A', 'B', 'C']) 
# A B C 
# 0 1 2 3 
# 1 4 5 6 
+0

, ale co mam zrobić, jeśli mam wiele indeksów? df1 = pd.DataFrame (lista_list, kolumny ["A", "B", "C"], indeks = ["A", "B"]) nie działa. Zły kształt. Więc jak? – pashute

Powiązane problemy