2013-09-05 3 views
10

Я использую python2.7 и pandas 0.11.0.pandas: заполнить столбец несколькими массивами numpy

Я пытаюсь заполнить столбец данных с помощью DataFrame.apply (func). Функция func() должна возвращать массив numpy (1x3).

import pandas as pd 
import numpy as np 

df= pd.DataFrame(np.random.randn(4, 3), columns=list('ABC')) 
print(df) 

       A   B   C 
    0 0.910142 0.788300 0.114164 
    1 -0.603282 -0.625895 2.843130 
    2 1.823752 -0.091736 -0.107781 
    3 0.447743 -0.163605 0.514052 

Функция используется для целей тестирования:

def test(row): 
    # some complex calc here 
    # based on the values from different columns 
    return np.array((1,2,3)) 

df['D'] = df.apply(test, axis=1) 

[...] 
ValueError: Wrong number of items passed 1, indices imply 3 

Забавно, что когда я создаю dataframe с нуля, он работает довольно хорошо, и возвращается, как и ожидалось:

dic = {'A': {0: 0.9, 1: -0.6, 2: 1.8, 3: 0.4}, 
    'C': {0: 0.1, 1: 2.8, 2: -0.1, 3: 0.5}, 
    'B': {0: 0.7, 1: -0.6, 2: -0.1, 3: -0.1}, 
    'D': {0:np.array((1,2,3)), 
      1:np.array((1,2,3)), 
      2:np.array((1,2,3)), 
      3:np.array((1,2,3))}} 

df= pd.DataFrame(dic) 
print(df) 
     A B C   D 
    0 0.9 0.7 0.1 [1, 2, 3] 
    1 -0.6 -0.6 2.8 [1, 2, 3] 
    2 1.8 -0.1 -0.1 [1, 2, 3] 
    3 0.4 -0.1 0.5 [1, 2, 3] 

Заранее спасибо

+3

вы должны избегать использования '' list's/tuple's в '' DataFrame's или серии '. Почему не только 3 столбца в 'df' или отдельный' DataFrame' с вашими столбцами? –

+5

Я предполагаю, что иногда векторная форма более естественна для некоторого количества, например координат. Очевидно, что 'df.endPoint-df.startPoint' является более предпочтительным для' np.c_ [df.endX-df.startX, df.endY-df.startY, df.endZ-df.startZ] '. – herrlich10

ответ

11

Если вы попытаетесь вернуть несколько значений из функции, которая передается t o apply, а DataFrame, который вы вызываете apply, имеет то же количество элементов вдоль оси (в этом случае столбцы) в качестве числа возвращаемых значений, Pandas создаст DataFrame из возвращаемых значений с теми же ярлыками, что и оригинал DataFrame. Вы можете увидеть это, если вы просто сделать:

>>> def test(row): 
     return [1, 2, 3] 
>>> df= pd.DataFrame(np.random.randn(4, 3), columns=list('ABC')) 
>>> df.apply(test, axis=1) 
    A B C 
0 1 2 3 
1 1 2 3 
2 1 2 3 
3 1 2 3 

И именно поэтому вы получите ошибку, так как вы не можете назначить DataFrame к колонку DataFrame.

Если вы возвращаете любое другое число значений, он будет возвращать только объект серии, которые могут быть назначены:

>>> def test(row): 
     return [1, 2] 
>>> df= pd.DataFrame(np.random.randn(4, 3), columns=list('ABC')) 
>>> df.apply(test, axis=1) 
0 [1, 2] 
1 [1, 2] 
2 [1, 2] 
3 [1, 2] 
>>> df['D'] = df.apply(test, axis=1) 
>>> df 
      A   B   C  D 
0 0.333535 0.209745 -0.972413 [1, 2] 
1 0.469590 0.107491 -1.248670 [1, 2] 
2 0.234444 0.093290 -0.853348 [1, 2] 
3 1.021356 0.092704 -0.406727 [1, 2] 

Я не знаю, почему панды делает это, и почему он делает это только тогда, когда возвращаемое значение является list или ndarray, так как он не будет это делать, если вы вернетесь tuple в:

>>> def test(row): 
     return (1, 2, 3) 
>>> df= pd.DataFrame(np.random.randn(4, 3), columns=list('ABC')) 
>>> df['D'] = df.apply(test, axis=1) 
>>> df 
      A   B   C   D 
0 0.121136 0.541198 -0.281972 (1, 2, 3) 
1 0.569091 0.944344 0.861057 (1, 2, 3) 
2 -1.742484 -0.077317 0.181656 (1, 2, 3) 
3 -1.541244 0.174428 0.66(1, 2, 3) 
+1

Привет, Виктор! благодаря ответу. Итак, если я правильно вас понимаю, нет способа передать массив numpy? – Nic

+1

@Nic Если длина массива numpy не совпадает с количеством столбцов, то ваш код будет работать, но он не предназначен для использования таким образом. Поскольку Phillip Cloud сказал, что вам следует избегать размещения списков или массивов в вашей серии. Вы должны создать несколько рядов (то есть несколько столбцов в вашем DataFrame). –

+0

Спасибо, ребята. Затем я последую вашим советам и займусь 3 колонками. @Phillip: извините, я пропустил ваш комментарий при первом чтении. – Nic

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