Умножьте (или разделите) каждые n индексов DataFrame на константу из массива - PullRequest
0 голосов
/ 22 марта 2019

У меня есть DataFrame, и я хотел бы умножать (или делить) каждые n индексов на конкретное число из массива.Кратким примером является следующий, где буквы являются просто числами.

df =

   0  1
0  A  B
1  C  D
2  E  F
3  G  H
4  I  J
5  K  L
6  M  N
7  O  P

DataFrame (или массив numpy):

   0  1
0  W  X
1  Y  Z

Мне понравитсячтобы получить следующий результат:

Результат =

   0     1
0  A/W  B/X
1  C/Y  D/Z
2  E/W  F/X
3  G/Y  H/Z
4  I/W  J/X
5  K/Y  L/Z
6  M/W  N/X
7  O/Y  P/Z

Можно ли как-то решить эту проблему, используя df.groupy(df % 2).agg() или df.groupy(df % 2).apply()?Я работаю с огромным DataFrame, и я верю, что применение цикла for займет больше времени, чем необходимо.

Я знаю, что должен использовать функцию, но не могу написать ту, которая выполняет то, что я ищу.

Спасибо.

Ответы [ 3 ]

1 голос
/ 22 марта 2019

Попробуйте следующий код:

Начните с определения функции, которая будет применяться к каждой группе:

def dv(tbl):
    return tbl.divide(df2.values, axis='columns')

df2 преобразуется в базовый values для "освобождения" от выравнивания индекса.

Затем мы читаем количество строк в df2 (размер группы в группировке df ):

len2 = len(df2.index)

Тогда фактическое деление можно выполнить с помощью одной инструкции:

df.groupby(np.arange(len(df.index)) // len2).apply(dv)

np.arange(len(df.index)) // len2 обеспечивает деление df на группы, содержащие столько же строк, сколько и df2.

Для каждой группы применяется функция dv (определена выше).

Для целей тестирования я создал первый DataFrame ( df ) как:

      0     1
0  10.0  11.0
1  12.0  13.0
2  14.0  15.0
3  16.0  17.0
4  18.0  19.0
5  20.0  21.0
6  22.0  23.0
7  24.0  25.0

и второй ( df2 ) как:

     0    1
0  2.0  2.5
1  3.0  3.5

Результат был:

           0         1
0   5.000000  4.400000
1   4.000000  3.714286
2   7.000000  6.000000
3   5.333333  4.857143
4   9.000000  7.600000
5   6.666667  6.000000
6  11.000000  9.200000
7   8.000000  7.142857

Конечно, вышеуказанный код был для деления.

Если вы хотите умножить, то определите функцию:

def ml(tbl):
    return tbl.multiply(df2.values, axis='columns')

и примените его, позвонив:

df.groupby(np.arange(len(df.index)) // len2).apply(ml)
0 голосов
/ 22 марта 2019

Вы можете изменить индекс первого кадра данных следующим образом:

df.index = df.index % 2

Затем объединить с индексом:

df = df.join(df2, lsuffix='_l', rsuffix = '_r')

Тогда вы захотите что-нибудьвот так

df['ratio1'] = df['0_l'] / df['0_r']
df['ratio2'] = df['1_l'] / df['1_r']

Чтобы получить точную форму вашего ответа:

column_map = {'ratio1': 0, 'ratio2': 1}
df = df[['ratio1', 'ratio2']].rename(columns= column_map)
0 голосов
/ 22 марта 2019

Это должно сработать, не требуя цикла или использования apply:

df.iloc[::2, 0] = df.iloc[::2, 0] / df2.iloc[0, 0]
df.iloc[1::2, 0] = df.iloc[1::2, 0] / df2.iloc[0, 1]
df.iloc[::2, 1] = df.iloc[::2, 1] / df2.iloc[1, 0]
df.iloc[1::2, 1] = df.iloc[1::2, 1] / df2.iloc[1, 1]

Это также может работать и может использоваться с любым количеством столбцов:

df.iloc[::2, :] = df.iloc[::2, :] / df2.iloc[0, :]
df.iloc[1::2, :] = df.iloc[1::2, :] / df2.iloc[1, :]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...