Подтвердить что ты не робот

Pandas: Элементное умножение двух кадров данных

Я знаю, как выполнять умножение элементов по элементам между двумя фреймами Pandas. Однако все усложняется, когда размеры двух фреймов несовместимы. Например, ниже df * df2 является простым, но df * df3 является проблемой:

df = pd.DataFrame({'col1' : [1.0] * 5, 
                   'col2' : [2.0] * 5, 
                   'col3' : [3.0] * 5 }, index = range(1,6),)
df2 = pd.DataFrame({'col1' : [10.0] * 5, 
                    'col2' : [100.0] * 5, 
                    'col3' : [1000.0] * 5 }, index = range(1,6),)
df3 = pd.DataFrame({'col1' : [0.1] * 5}, index = range(1,6),)

df.mul(df2, 1) # element by element multiplication no problems

df.mul(df3, 1) # df(row*col) is not equal to df3(row*col)
   col1  col2  col3
1   0.1   NaN   NaN
2   0.1   NaN   NaN
3   0.1   NaN   NaN
4   0.1   NaN   NaN
5   0.1   NaN   NaN

В приведенной выше ситуации как я могу умножить каждый столбец df с помощью df3.col1?

Моя попытка: Я попытался реплицировать df3.col1 len(df.columns.values) раз, чтобы получить фреймворк данных того же размера, что и df:

df3 = pd.DataFrame([df3.col1 for n in range(len(df.columns.values)) ])
df3
        1    2    3    4    5
col1  0.1  0.1  0.1  0.1  0.1
col1  0.1  0.1  0.1  0.1  0.1
col1  0.1  0.1  0.1  0.1  0.1

Но это создает dataframe размеров 3 * 5, тогда как я после 5 * 3. Я знаю, что могу взять транспонирование с помощью df3.T(), чтобы получить то, что мне нужно, но я думаю, что это не самый быстрый способ.

4b9b3361

Ответ 1

In [161]: pd.DataFrame(df.values*df2.values, columns=df.columns, index=df.index)
Out[161]: 
   col1  col2  col3
1    10   200  3000
2    10   200  3000
3    10   200  3000
4    10   200  3000
5    10   200  3000

Ответ 2

Простейший способ сделать это - просто умножить фрейм данных, чьи имена кодов вы хотите сохранить со значениями (например, массив numpy) другого, например:

In [63]: df * df2.values
Out[63]: 
   col1  col2  col3
1    10   200  3000
2    10   200  3000
3    10   200  3000
4    10   200  3000
5    10   200  3000

Таким образом, вам не нужно записывать все новые шаблоны DataFrame.

Ответ 3

Другой способ - создать список столбцов и присоединиться к ним:

cols = [pd.DataFrame(df[col] * df3.col1, columns=[col]) for col in df]
mul = cols[0].join(cols[1:])

Ответ 4

Это работает для меня:

mul = df.mul(df3.c, axis=0)

Или, если вы хотите вместо этого вычесть (делить):

sub = df.sub(df3.c, axis=0)
div = df.div(df3.c, axis=0)

Работает также с nan в df (например, если вы примените это к df: df.iloc[0]['col2'] = np.nan)