2015-09-05 2 views
2

Есть 2 Dataframes формы (6, 4) и (6,2). Требуется выполнить умножение элементов по 2 кадрам данных.Element wise Умножение 2 DataFrames

>>> import pandas as pd 
>>> df1 = pd.DataFrame({'col1' : [1,2,6,8,-1,3], 'col2' : [1,2,6,8,-1,3], 'col3' : [1,2,6,8,-1,3], 'col4' : [1,2,6,8,-1,3]}) 
>>> df1 
    col1 col2 col3 col4 
0  1  1  1  1 
1  2  2  2  2 
2  6  6  6  6 
3  8  8  8  8 
4 -1 -1 -1 -1 
5  3  3  3  3 
>>> 
>>> df2 = pd.DataFrame({'col1' : [9,8,7,1,1,1], 'col2' : [11,12,16,2,2,1]}) 
>>> df2 
    col1 col2 
0  9 11 
1  8 12 
2  7 16 
3  1  2 
4  1  2 
5  1  1 

Ожидаемый результат:

0  9  9  9  9  
1  16 16  16  16  
2  42 42  42  42  
3  8  8  8  8  
4  -1 -1  -1  -1  
5  3  3  3  3  

0 11  11  11  11 
1 24  24  24  24 
2 96  96  96  96 
3 16  16  16  16 
4 -2  -2  -2  -2 
5 3  3  3  3 

Подход 1:

a = np.array(df1.values) 
b = np.array(df2.values) 

Пробовал ниже способов,

c = a * b 

Ошибка: #ValueError: операнды не могут передаваться вместе с формы (6, 4) и (6,2)

подход 2:

Старинная 1 из dataframes в серии.

df_temp=df1[df1.columns.values['a']] 
func = lambda x: np.asarray(x) * np.asarray(df2[df2.columns.values[0]]) 

df_temp.apply(func) 

Выход: Не получать элементный мудрый выход.

подход 3:

Преобразование DF в список и умножать списки:

df11=list(df1.values.flatten()) 
df22=list(df2.values.flatten()) 

Но результирующий список не является 2 мерная ;. Его 1 размер.

ответ

1

Вы должны использовать. умножать():

import pandas as pd 

df1 = pd.DataFrame({'col1' : [1,2,6,8,-1,3], 'col2' : [1,2,6,8,-1,3], 
    'col3' : [1,2,6,8,-1,3], 'col4' : [1,2,6,8,-1,3]}) 
df2 = pd.DataFrame({'col1' : [9,8,7,1,1,1], 'col2' : [11,12,16,2,2,1]}) 

for x in range(len(df2.columns)): 
    new_df = df1.multiply(df2.iloc[:, x], axis=0) 
    print new_df 

Это возвращает:

col1 col2 col3 col4 
0  9  9  9  9 
1 16 16 16 16 
2 42 42 42 42 
3  8  8  8  8 
4 -1 -1 -1 -1 
5  3  3  3  3 

    col1 col2 col3 col4 
0 11 11 11 11 
1 24 24 24 24 
2 96 96 96 96 
3 16 16 16 16 
4 -2 -2 -2 -2 
5  3  3  3  3 
+0

Вот ссылка на документацию на .multiply(): http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.multiply.html – Alex

1

Если вы нормально получать выходные данные в виде Numpy массивов, таким образом, работает

map(lambda col: df2[col].values.reshape(-1, 1) * df1.values, df2) 

EDIT: Это чистый и дает выход в виде панд ДФС:

map(lambda col: df1.mul(df2[col], axis=0), df2) 
+0

Спасибо @sjosund .. попробовал этот подход. Это дает возможность масштабирования. Как только я увеличил форму dataframe до (35000,100) и (35000,2); умножение идет медленнее ... Процесс продолжался 20 минут. Затем я его убил. – shankar

1

Вы должны быть в состоянии создать результат, который вы ищете с:

>>> [df1.apply(lambda x: x*y) for _, y in df2.iteritems()] 
[ col1 col2 col3 col4 
0  9  9  9  9 
1 16 16 16 16 
2 42 42 42 42 
3  8  8  8  8 
4 -1 -1 -1 -1 
5  3  3  3  3, 
    col1 col2 col3 col4 
0 11 11 11 11 
1 24 24 24 24 
2 96 96 96 96 
3 16 16 16 16 
4 -2 -2 -2 -2 
5  3  3  3  3] 

Или используя @Alex подход многократно, это будет делать то же самое. Вы также можете Concat их в один многоиндексной dataframe:

>>> pd.concat((df1.mul(y, axis=0) for _, y in df2.iteritems()), axis=1, keys=df2) 
    col1    col2    
    col1 col2 col3 col4 col1 col2 col3 col4 
0 9 9 9 9 11 11 11 11 
1 16 16 16 16 24 24 24 24 
2 42 42 42 42 96 96 96 96 
3 8 8 8 8 16 16 16 16 
4 -1 -1 -1 -1 -2 -2 -2 -2 
5 3 3 3 3 3 3 3 3 
+0

Спасибо @Alex за подробности .. Не могли бы вы подробный синтаксис: df1.mul (y, axis = 0) для _, y в df2.iteritems()), axis = 1, keys = df2 – shankar

+0

Синтаксис выглядит следующим образом. .mul() или .multiply() в более поздних версиях pandas берет серию, dataframe или константу в качестве единственного требуемого аргумента. Установка оси на ноль означает, что вы будете умножать элементы после их выравнивания по оси индекса. Наконец, цикл for использует iteritems() для выбора каждого столбца блока данных df2 по одному за раз. При выводе такого типа эти столбцы становятся рядами панд, и каждый из них передается в свою очередь команде df1.mul (y, axis = 0). Это понимание списка показано как цикл for в моем ответе выше. – Alex

0

Спасибо @Alex для деталей ..

(df1.mul (у, ось = 0) для _, у в df2.iteritems())

+0

'df1.mul (y, axis = 0)' умножает df1 на y, но использует индекс (ось = 0) против столбца, эффективно перенося до умножения. Остальное - это генератор, проходящий через каждый столбец в df2 и присваивающий его y, поиск понятий и генераторов. – AChampion

Смежные вопросы