Вставте рядок у кадр даних панди


112

У мене є кадр даних:

s1 = pd.Series([5, 6, 7])
s2 = pd.Series([7, 8, 9])

df = pd.DataFrame([list(s1), list(s2)],  columns =  ["A", "B", "C"])

   A  B  C
0  5  6  7
1  7  8  9

[2 rows x 3 columns]

і мені потрібно додати перший рядок [2, 3, 4], щоб отримати:

   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

Я спробував append()іconcat() функціонувати, але не можу знайти правильний спосіб, як це зробити.

Як додати / вставити ряд у кадр даних?


6
зауважте, що краще використовувати s1.valuesна відміну від того, list(s1)як ви будете створювати абсолютно новий список, використовуючи list(s1).
acushner

7
Я не розумію, чому всі так люблять панди, коли щось таке, що повинно бути таким простим, такий біль у попі і так повільно.
MattCochrane

Відповіді:


145

Просто призначте рядок певному індексу, використовуючи loc:

 df.loc[-1] = [2, 3, 4]  # adding a row
 df.index = df.index + 1  # shifting index
 df = df.sort_index()  # sorting by index

І ви отримуєте, як бажаєте:

    A  B  C
 0  2  3  4
 1  5  6  7
 2  7  8  9

Дивіться в документації Pandas Індексація: Налаштування із збільшенням .


2
Якщо ви не хочете , щоб встановити з розширенням, але вкладишем всередині dataframe, поглянути на stackoverflow.com/questions/15888648 / ...
FooBar

6
альтернатива зміщення індексу: df.sort (). reset_index (drop = True)
Meloun

2
df.sort є застарілим, використовуйте df.sort_index ()
GBGOLC

1
@Piotr - це чудово працює, але що відбувається, коли ви хочете скопіювати рядок із кадру даних, наприклад df.loc[-1] = df.iloc[[0]], і вставити це? Кадр містить доданий стовпчик індексу, що дає помилку ValueError: cannot set a row with mismatched columns (див. Stackoverflow.com/questions/47340571/… )
Growler

5
Я думаю df.loc[-1] = [2, 3, 4] # adding a row, це трохи оманливо, як -1це не останній рядок / елемент, як це стосується масивів Python.
flow2k

26

Не впевнений, як ви дзвонили, concat()але це має працювати до тих пір, поки обидва об'єкти одного типу. Можливо, проблема полягає в тому, що вам потрібно передати свій другий вектор у кадр даних? Використовуючи df, який ви визначили, для мене працює наступне:

df2 = pd.DataFrame([[2,3,4]], columns=['A','B','C'])
pd.concat([df2, df])

Найкраща відповідь ^ :)
Cam.Davidson.Pilon

23

Один із способів цього досягти

>>> pd.DataFrame(np.array([[2, 3, 4]]), columns=['A', 'B', 'C']).append(df, ignore_index=True)
Out[330]: 
   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

Як правило, найпростіше додавати фрейми даних, а не серії. У вашому випадку, оскільки ви хочете, щоб новий рядок був "вгорі" (зі стартовим ідентифікатором), і немає функції pd.prepend(), я спершу створюю новий кадр даних, а потім додаю ваш старий.

ignore_indexігнорує старий поточний індекс у вашому фреймі даних та гарантує, що перший рядок насправді починається з індексу, 1а не перезапускається з індексом 0.

Типовий застереження: Cetero censeo ... додавання рядків є досить неефективною операцією. Якщо ви дбаєте про продуктивність і можете якось забезпечити, щоб спершу створити фрейм даних з правильним (довшим) індексом, а потім просто вставити додатковий рядок у кадр даних, ви обов'язково повинні це зробити. Побачити:

>>> index = np.array([0, 1, 2])
>>> df2 = pd.DataFrame(columns=['A', 'B', 'C'], index=index)
>>> df2.loc[0:1] = [list(s1), list(s2)]
>>> df2
Out[336]: 
     A    B    C
0    5    6    7
1    7    8    9
2  NaN  NaN  NaN
>>> df2 = pd.DataFrame(columns=['A', 'B', 'C'], index=index)
>>> df2.loc[1:] = [list(s1), list(s2)]

Поки ми маємо те, що у вас було df:

>>> df2
Out[339]: 
     A    B    C
0  NaN  NaN  NaN
1    5    6    7
2    7    8    9

Але тепер ви можете легко вставити рядок наступним чином. Оскільки простір було попередньо розподілено, це більш ефективно.

>>> df2.loc[0] = np.array([2, 3, 4])
>>> df2
Out[341]: 
   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

Це приємне рішення для вирішення проблем, я намагався вставити серії в рамки даних. Наразі це мені досить добре.
Мелун

Мені найбільше подобається останній варіант. Це справді відповідає тому, що я дійсно хочу зробити. Дякую @FooBar!
Jade Cacho

13

Я зібрав коротку функцію, яка дозволяє трохи більше гнучкості при вставці рядка:

def insert_row(idx, df, df_insert):
    dfA = df.iloc[:idx, ]
    dfB = df.iloc[idx:, ]

    df = dfA.append(df_insert).append(dfB).reset_index(drop = True)

    return df

які можна було б додатково скоротити до:

def insert_row(idx, df, df_insert):
    return df.iloc[:idx, ].append(df_insert).append(df.iloc[idx:, ]).reset_index(drop = True)

Тоді ви можете використовувати щось на кшталт:

df = insert_row(2, df, df_new)

де 2позиція індексу, dfкуди ви хочете вставити df_new.


7

Ми можемо використовувати numpy.insert. Це має перевагу гнучкості. Вам потрібно лише вказати індекс, у який ви хочете вставити.

s1 = pd.Series([5, 6, 7])
s2 = pd.Series([7, 8, 9])

df = pd.DataFrame([list(s1), list(s2)],  columns =  ["A", "B", "C"])

pd.DataFrame(np.insert(df.values, 0, values=[2, 3, 4], axis=0))

    0   1   2
0   2   3   4
1   5   6   7
2   7   8   9

Тому що np.insert(df.values, 0, values=[2, 3, 4], axis=0)0 вказує функції, яку місце / індекс ви хочете розмістити нові значення.


6

це може здатися надто простим, але неймовірним є те, що проста функція вставлення нового рядка не вбудована. Я багато читав про додавання нового df до оригіналу, але мені цікаво, чи буде це швидше.

df.loc[0] = [row1data, blah...]
i = len(df) + 1
df.loc[i] = [row2data, blah...]

Ви мали на увазі "додавання нового df" або просто "додавання нового рядка", як показує ваш код?
smci

вибачте, мій вирок не був зрозумілим. я читав рішення інших людей, які стискають / додають цілком новий кадр даних лише одним рядком. але в моєму рішенні його лише один рядок у існуючому фреймі даних не потрібно створювати додатковий кадр даних
Аарон Мелгар

6

Нижче було б найкращим способом вставити рядок у рамки даних панди, не сортуючи та повторно налаштувавши індекс:

import pandas as pd

df = pd.DataFrame(columns=['a','b','c'])

def insert(df, row):
    insert_loc = df.index.max()

    if pd.isna(insert_loc):
        df.loc[0] = row
    else:
        df.loc[insert_loc + 1] = row

insert(df,[2,3,4])
insert(df,[8,9,0])
print(df)

чому б ви сказали, що це найкращий спосіб?
Юка

то було б добре надати докази на підтвердження цієї вимоги, ви встигли?
Юка

1
ви можете використовувати pd.isna, щоб не імпортувати numpy
kato2

2

Додавати рядок у панди досить просто DataFrame:

  1. Створіть звичайний словник Python з тими ж назвами стовпців, що і ваш Dataframe;

  2. Використовуйте pandas.append()метод і введіть ім’я свого словника, де .append()це метод на екземплярах DataFrame;

  3. Додайте ignore_index=Trueвідразу після імені словника.


Це, мабуть, найбільш переважний варіант (близько 2020 року).
Девід Голембовський

1

concat()здається, трохи швидше, ніж вставлення та перевстановлення останнього рядка. У випадку, якщо хтось задумається про швидкість двох верхніх підходів:

In [x]: %%timeit
     ...: df = pd.DataFrame(columns=['a','b'])
     ...: for i in range(10000):
     ...:     df.loc[-1] = [1,2]
     ...:     df.index = df.index + 1
     ...:     df = df.sort_index()

17,1 с ± 705 мс на цикл (середнє ± ст. Розряд 7 прогонів, по 1 петлі кожен)

In [y]: %%timeit
     ...: df = pd.DataFrame(columns=['a', 'b'])
     ...: for i in range(10000):
     ...:     df = pd.concat([pd.DataFrame([[1,2]], columns=df.columns), df])

6,53 с ± 127 мс на цикл (середнє ± ст. Розряд 7 прогонів, по 1 петлі кожен)


0

Ви можете просто додати рядок до кінця DataFrame, а потім відрегулювати індекс.

Наприклад:

df = df.append(pd.DataFrame([[2,3,4]],columns=df.columns),ignore_index=True)
df.index = (df.index + 1) % len(df)
df = df.sort_index()

Або використовувати concatяк:

df = pd.concat([pd.DataFrame([[1,2,3,4,5,6]],columns=df.columns),df],ignore_index=True)

-1

Найпростіший спосіб додати рядок у кадр даних панди:

DataFrame.loc[ location of insertion ]= list( )

Приклад:

DF.loc[ 9 ] = [ ´Pepe , 33, ´Japan ]

Примітка: довжина вашого списку повинна відповідати довжині кадру даних.


зробив трюк для мене!
Сем Шоу
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.