Эффективно рассчитать разницу между двумя строками в кадре данных - PullRequest
0 голосов
/ 22 января 2019

Считайте, что у меня есть кадр данных, как показано ниже:

>>> import pandas as pd
>>> import numpy as np
>>> df = pd.DataFrame([[1, 2], [3, 4]], columns=['f1', 'f2'], index=['r1', 'r2'])
>>> df
    f1  f2
r1   1   2
r2   3   4

Как эффективно рассчитать абсолютную разницу между строками r1 и r2 и создать еще одну строку как r3, чтобы сохранить результат. То есть результат будет выглядеть так:

>>> for cn in df.columns:
...     diff_dat.append(abs(df[cn]['r1'] - df[cn]['r2']))
... 
>>> diff_dat
[2, 2]
>>> df.append(pd.DataFrame([diff_dat], index=['r3'], columns=df.columns))
    f1  f2
r1   1   2
r2   3   4
r3   2   2

Ответы [ 3 ]

0 голосов
/ 22 января 2019

Вы можете сделать это:

In [576]: df.append(df.diff().dropna().abs())
Out[583]: 
     f1   f2
r1  1.0  2.0
r2  3.0  4.0
r2  2.0  2.0
0 голосов
/ 22 января 2019

Самым простым решением для этого является использование функции .loc, которая принимает индексы строк.

(отредактировано для удаления кода, идентичного написанному jezrael)

Если вы не знакомы с пандами, я бы посоветовал проверить функцию DataFrame.apply, поскольку она позволяет выполнять более широкие манипуляции с данными (как по строкам, так и по столбцам). Решение будет выглядеть так:

df["r3"] = df.apply(lambda c: abs(c["r1"] - c["r2"]), axis=0)

pandas.DataFrame.apply - это мощный инструмент, позволяющий вам применять функции к строкам или столбцам в наборе данных и использующий преимущества векторизации панд.

0 голосов
/ 22 января 2019

Используйте loc для выбора строк, вычитания, получения abs и последнего добавления новой строки на setting with enlargement:

df.loc['r3'] = (df.loc['r1'] - df.loc['r2']).abs()
print (df)
    f1  f2
r1   1   2
r2   3   4
r3   2   2

Производительность на 1000 столбцов:

np.random.seed(123)
df = pd.DataFrame(np.random.randint(10, size=(2, 1000)), index=['r1', 'r2']).add_prefix('f')-5

#Mayank Porwal solution
In [40]: %timeit df.append(df.diff().dropna().abs())
1.51 ms ± 19.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

#jezrael solution
In [41]: %timeit df.loc['r3'] = (df.loc['r1'] - df.loc['r2']).abs()
663 µs ± 54.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

#NaT3z solution
In [42]: %timeit df.loc["r3"] = df.apply(lambda c: abs(c["r1"] - c["r2"]), axis=0)
967 µs ± 80.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Для повышения производительности возможно использование numpy:

In [49]: %timeit df.loc['r3'] = np.abs(df.loc['r1'].values - df.loc['r2'].values)
414 µs ± 1.68 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...