Панди Python: заповнюйте кадр даних за рядком


133

Просте завдання додати рядок до pandas.DataFrameоб'єкта, здається, важко виконати. З цим пов'язано 3 запитання про стаціонарний потік, жодне з яких не дає діючої відповіді.

Ось що я намагаюся зробити. У мене є DataFrame, з якого я вже знаю форму, а також назви рядків і стовпців.

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

Тепер у мене є функція ітераційно обчислювати значення рядків. Як я можу заповнити один із рядків словником чи а pandas.Series? Ось різні спроби, які не вдалися:

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

Мабуть, він намагався додати стовпчик замість рядка.

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

Дуже неінформативне повідомлення про помилку.

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

Мабуть, це лише для встановлення окремих значень у кадрі даних.

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

Ну, я не хочу ігнорувати індекс, інакше ось результат:

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

Він вирівняв назви стовпців зі значеннями, але втратив мітки рядків.

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

Це теж невдало провалилось.

То як же це зробити?

Відповіді:


92

df['y'] встановить стовпчик

оскільки ви хочете встановити рядок, використовуйте .loc

Зауважте, що .ixтут еквівалент, ваш не вдався, оскільки ви намагалися призначити словник кожному елементу рядка, yймовірно, не так, як вам потрібно; перехід до серії повідомляє пандам про те, що ви хочете вирівняти вхід (наприклад, тоді вам не потрібно вказувати всі елементи)

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

Я бачу. Отже, locатрибут фрейму даних визначає особливий, __setitem__який виконує магію, яку я думаю.
xApple

Чи можете ви побудувати це за один прохід (тобто зі стовпцями, індексами та у)?
Енді Хайден

5
Отже, якщо я можу генерувати по одному рядку за раз, як би я сконструював кадр даних оптимально?
xApple

Чи очікував якийсь варіант df = pd.DataFrame({'y': pd.Series(y)}, columns=['a','b','c','d'], index=['x','y','z'])роботи?
Енді Хейден

@xApple проблематика найкраще для вас, щоб скласти список диктів (або список), а потім просто перейти до конструктора, буде набагато ефективніше
Джефф

71

Мій підхід був, але я не можу гарантувати, що це найшвидше рішення.

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

4
Це блискуче працювало для мене, і мені подобається те, що ви явно отримуєте appendдані до фрейму даних.
Джоні Брукс

1
Зауважте, що ця відповідь потребує кожного рядка для додавання назви стовпця. Те саме для прийнятої відповіді.
пашуте

Це також працює, якщо ви не знаєте кількість рядків заздалегідь.
Ірен

34

Це більш проста версія

import pandas as pd
df = pd.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>']`

4
просто хочу запитати, чи ефективний цей процесор і пам'ять?
czxttkl

1
як я можу знати останній рядок df, щоб кожного разу додавати його до останнього?
пашуте

25

Якщо вхідні рядки - це списки, а не словники, то наступне - просте рішення:

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

але що робити, якщо у мене є мультиіндекс? df1 = pd.DataFrame (list_of_lists, стовпці ['A', 'B', 'C'], index = ['A', 'B']) не працює. Неправильна форма. Так як?
пашуте
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.