pandas dataframe умножить на ряд

22

Каков наилучший способ умножить все столбцы Pandas DataFrame на вектор столбца, хранящийся в Series ? Раньше я делал это в Matlab с repmat() , которого нет в Pandas. Я могу использовать np.tile() , но выглядит уродливо, чтобы каждый раз преобразовывать структуру данных.

Спасибо.

    
задан jianpan 31.10.2012 в 21:20
источник
  • Почему вы не можете просто использовать numpy? какую функциональность вам нужно от панд? –  Andy Hayden 01.11.2012 в 14:22

3 ответа

36

Что не так с

result = dataframe.mul(series, axis=0)

?

Ссылка

    
ответ дан Wes McKinney 09.11.2012 в 22:01
источник
  • Я просто не знал о DataFrame.mul! Гораздо проще сделать это. –  spencerlyon2 15.11.2012 в 21:58
  • Не работал для меня. Я получаю: TypeError: не может умножить последовательность на non-int типа 'float' –  James Hirschorn 31.01.2017 в 03:39
10

Это можно выполнить довольно просто с помощью метода DataFrame apply .

In[1]: import pandas as pd; import numpy as np

In[2]: df = pd.DataFrame(np.arange(40.).reshape((8, 5)), columns=list('abcde')); df
Out[2]: 
        a   b   c   d   e
    0   0   1   2   3   4
    1   5   6   7   8   9
    2  10  11  12  13  14
    3  15  16  17  18  19
    4  20  21  22  23  24
    5  25  26  27  28  29
    6  30  31  32  33  34
    7  35  36  37  38  39

In[3]: ser = pd.Series(np.arange(8) * 10); ser
Out[3]: 
    0     0
    1    10
    2    20
    3    30
    4    40
    5    50
    6    60
    7    70

Теперь, когда у нас есть DataFrame и Series , нам нужна функция для перехода к apply .

In[4]: func = lambda x: np.asarray(x) * np.asarray(ser)

Мы можем передать это df.apply , и нам хорошо идти

In[5]: df.apply(func)
Out[5]:
          a     b     c     d     e
    0     0     0     0     0     0
    1    50    60    70    80    90
    2   200   220   240   260   280
    3   450   480   510   540   570
    4   800   840   880   920   960
    5  1250  1300  1350  1400  1450
    6  1800  1860  1920  1980  2040
    7  2450  2520  2590  2660  2730

df.apply действует по умолчанию по столбцу, но он также может действовать по-разному, передав axis=1 в качестве аргумента для apply .

In[6]: ser2 = pd.Series(np.arange(5) *5); ser2
Out[6]: 
    0     0
    1     5
    2    10
    3    15
    4    20

In[7]: func2 = lambda x: np.asarray(x) * np.asarray(ser2)

In[8]: df.apply(func2, axis=1)
Out[8]: 
       a    b    c    d    e
    0  0    5   20   45   80
    1  0   30   70  120  180
    2  0   55  120  195  280
    3  0   80  170  270  380
    4  0  105  220  345  480
    5  0  130  270  420  580
    6  0  155  320  495  680
    7  0  180  370  570  780

Это можно сделать более кратко, указав анонимную функцию внутри apply

In[9]: df.apply(lambda x: np.asarray(x) * np.asarray(ser))
Out[9]: 
          a     b     c     d     e
    0     0     0     0     0     0
    1    50    60    70    80    90
    2   200   220   240   260   280
    3   450   480   510   540   570
    4   800   840   880   920   960
    5  1250  1300  1350  1400  1450
    6  1800  1860  1920  1980  2040
    7  2450  2520  2590  2660  2730

In[10]: df.apply(lambda x: np.asarray(x) * np.asarray(ser2), axis=1)
Out[10]:
       a    b    c    d    e
    0  0    5   20   45   80
    1  0   30   70  120  180
    2  0   55  120  195  280
    3  0   80  170  270  380
    4  0  105  220  345  480
    5  0  130  270  420  580
    6  0  155  320  495  680
    7  0  180  370  570  780
    
ответ дан spencerlyon2 04.11.2012 в 07:52
источник
1

Почему бы не создать свою собственную функцию фреймворка:

def tile_df(df, n, m):
    dfn = df.T
    for _ in range(1, m):
        dfn = dfn.append(df.T, ignore_index=True)
    dfm = dfn.T
    for _ in range(1, n):
        dfm = dfm.append(dfn.T, ignore_index=True)
    return dfm

Пример:

df = pandas.DataFrame([[1,2],[3,4]])
tile_df(df, 2, 3)
#    0  1  2  3  4  5
# 0  1  2  1  2  1  2
# 1  3  4  3  4  3  4
# 2  1  2  1  2  1  2
# 3  3  4  3  4  3  4

Однако , документы note: «DataFrame не предназначен для замены для ndarray, так как семантика индексирования в разных местах от матрицы значительно отличается». Предположительно, это должно интерпретироваться как «используйте numpy, если вы делаете много материала матрицы» .

    
ответ дан Andy Hayden 31.10.2012 в 22:28
источник
  • Спасибо за ответ. Но мне нужно умножить элементарно. в matlab это может быть df. * repmat (s, 1, 2). Возможно, лучший способ - передать data.frame в ndarray. –  jianpan 01.11.2012 в 14:08
  • @jianpan Я вижу, я не понял repmat / tile ... Я думаю, что совет будет просто использовать numpy? –  Andy Hayden 01.11.2012 в 14:18
  • @jianpan Как насчет этой пользовательской функции плитки? –  Andy Hayden 01.11.2012 в 17:21
  • Спасибо, Хайден. Я колебался, чтобы преобразовать df в ndarray здесь, потому что после умножения на элементы мне нужны данные обратно в df для других вычислений. Я думал, что это может быть что-то существовавшее в Пандах, поскольку шкала по столбцу - очень распространенная операция в финансовом приложении. –  jianpan 06.11.2012 в 18:47