2013-08-17 2 views
1

Есть ли способ выполнить операцию между двумя кадрами данных?Операции между двумя кадрами данных или эквивалентно между двумя многомерными массивами

Например, предположим, что мы имеем пару dataframes:

df1 = pd.DataFrame({'a': randn(5), 'b': randn(5)}) 
df2 = pd.DataFrame({'c': randn(5), 'd': randn(5)}) 

df1 
      a   b 
0 -0.287740 -0.255126 
1 -0.356745 0.632524 
2 -0.379608 -0.876348 
3 -0.596401 0.937805 
4 0.969356 0.421352 

df2 
      c   d 
0 -0.505406 -0.921449 
1 0.508703 0.844641 
2 0.300125 -0.942838 
3 0.711138 -0.364033 
4 -0.370174 -1.284353 

И я хотел бы, чтобы выполнить операцию (возможно, корреляция) между рядами df1 и df2. Используя этот пример, я хочу что-то подобное в новом dataframe:

corr([-0.287740 -0.255126],[-0.505406 -0.921449]) 
corr([-0.356745 0.632524],[0.508703 0.844641]) 
... 
corr([0.969356 0.421352],[-0.370174 -1.284353]) 

Несмотря на то, используя соответствующие столбцы также можно просто перестановкой DF1 и df2.

Я думаю, что это должно быть возможно, хотя исходная задача была связана с Numpy массивы, которые будут сформулировать следующим образом:

Предположим пару массивов я и J:

i = np.random.random((5,2)) 
j = np.random.random((5,2)) 

i 
array([[ 0.88005044, 0.60633474], 
     [ 0.1183816 , 0.61705454], 
     [ 0.24259704, 0.8490759 ], 
     [ 0.66581795, 0.31805491], 
     [ 0.89337085, 0.21212527]]) 

j 
array([[ 0.52745975, 0.07748147], 
     [ 0.36152729, 0.74438265], 
     [ 0.48207699, 0.28462384], 
     [ 0.08623375, 0.55043213], 
     [ 0.26371755, 0.23409753]]) 

Как я могу сопоставить первый массив i [ 0.88005044, 0.60633474] с первым массивом j [ 0.52745975, 0.07748147]?

+0

Я удалил свой предыдущий комментарий, так как пропустил запятые на моем первом проходе :) –

+0

Конечно. Я забыл закрыть правый кронштейн. Я исправлю это через мгновение. –

+0

Также, о какой корреляции вы говорите здесь? Кросс-корреляция, стандартный Pearson's r и т. Д. Какой? –

ответ

2

Для Numpy вещи (которая была ваша первоначальная задача) должна не только:

map(np.correlate, i, j) 

решить?

>>> i = np.random.random((3,2)) 
>>> j = np.random.random((3,2)) 
>>> i 
array([[ 0.19553363, 0.88041704], 
     [ 0.15929013, 0.95699672], 
     [ 0.83473442, 0.9943525 ]]) 
>>> j 
array([[ 0.25712069, 0.37596445], 
     [ 0.35283409, 0.73069007], 
     [ 0.48959406, 0.17451211]]) 
>>> map(np.correlate, i, j) 
[array([ 0.38128125]), 
array([ 0.75547099]), 
array([ 0.58220756])] 

Update: Благодаря @PhillipCloud для короткой версии намека.

+0

Именно такой ответ я ожидал найти. Я попробую в одно мгновение. Большое спасибо. –

+0

Немного более чистая версия будет «map (correlate, i, j)». Вы также избегаете некоторых накладных расходов с использованием 'lambda', вариационных функций и' zip'. –

+0

Да, намного чище, спасибо :), я изменю код, но на удивление не быстрее: -/ –

1

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

df1 = DataFrame(randn(10, 2)) 
df2 = DataFrame(randn(10, 2)) 
result = DataFrame(empty((2, 2))) 
for (i, coli) in df1.iteritems(): 
    for (j, colj) in df2.iteritems(): 
     result.iloc[i, j] = coli.corr(colj) 
result 

Выход:

 0  1 
0 -0.071 0.726 
1 0.316 -0.277 

Это будет масштабироваться с n * m где n == df1.shape[1] и m == df2.shape[1] поэтому вы должны транспонировать оси либо (вы сказали выше, что у вас есть возможность для сделайте это) так, чтобы наименьшая ось была осью колонок.

ОБНОВЛЕНИЕ: Я полностью забыл про DataFrame.corrwith()!

In [12]: 

df1 = DataFrame(rand(100000, 20)) 
df2 = DataFrame(rand(100000, 20)) 
c1 = df1.corrwith(df2) 
c1 

Out[12]: 
0 -0.003 
1  0.000 
2  0.001 
3 -0.005 
4  0.002 
5  0.000 
6 -0.001 
7  0.003 
8  0.001 
9  0.007 
10 -0.003 
11 0.003 
12 0.006 
13 0.003 
14 -0.004 
15 0.001 
16 -0.000 
17 0.001 
18 0.003 
19 -0.001 
dtype: float64 

In [13]: 

timeit df1.corrwith(df2) 
10 loops, best of 3: 154 ms per loop 

In [14]: 

a, b = df1.values.T, df2.values.T 
c2 = map(correlate, a, b) 
c2 

Out[14]: 
[array([ 24903.2259]), 
array([ 25006.8102]), 
array([ 25020.8546]), 
array([ 24929.0867]), 
array([ 24991.4906]), 
array([ 25040.7961]), 
array([ 24916.7744]), 
array([ 25073.9599]), 
array([ 25080.4035]), 
array([ 25102.4981]), 
array([ 24894.667]), 
array([ 25071.7446]), 
array([ 25068.3474]), 
array([ 25104.1667]), 
array([ 24904.1676]), 
array([ 25115.5725]), 
array([ 25019.9898]), 
array([ 25055.4906]), 
array([ 24957.8537]), 
array([ 25054.7859])] 

In [15]: 

timeit map(correlate, a, b) 
10 loops, best of 3: 27.9 ms per loop 

In [16]: 

df1_nans = df1[df1 > 0.5] 
df2_nans = df2[df2 > 0.5] 
c1_nans = df1_nans.corrwith(df2_nans) 

In [17]: 

timeit df1_nans.corrwith(df2_nans) 
10 loops, best of 3: 163 ms per loop 

In [18]: 

a_nans, b_nans = df1_nans.values.T, df2_nans.values.T 
map(correlate, a_nans, b_nans) 

Out[18]: 
[array([ nan]), 
array([ nan]), 
array([ nan]), 
array([ nan]), 
array([ nan]), 
array([ nan]), 
array([ nan]), 
array([ nan]), 
array([ nan]), 
array([ nan]), 
array([ nan]), 
array([ nan]), 
array([ nan]), 
array([ nan]), 
array([ nan]), 
array([ nan]), 
array([ nan]), 
array([ nan]), 
array([ nan]), 
array([ nan])] 

Итак, повторим, correlate (в сторону от предоставления другого результата, потому что это другая функция) совершенно не на объекты с nan значениями. corrwith с другой стороны не терпит неудачу (и более гибкий для загрузки), но примерно в 3 раза медленнее.

+0

Ну, я думал о чем-то подобном вашему решению, однако я не преследовал его дальше, потому что я хочу применить его к миллионам строк, поэтому я боюсь, что это не будет хорошо масштабироваться. –

+0

Каковы размеры рамки? Являются ли они большими в обоих измерениях? Или у вас есть миллионы строк и всего несколько столбцов. –

+0

Это варьируется, но есть несколько миллионов примерно (1000,40). –