Панди 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.