2016-07-01 3 views
3

데이터 프레임 요소 안에 배열이 포함 된 팬더 데이터 프레임을 사용하고 있습니다. 이 요소에 함수를 "적용"한 다음 배열을 반환하려고합니다. 그러나 나는 매우 모순 된 행동을하고 있습니다. 함수는 처음 몇 번 제대로 실행되지만 실패합니다. 여기 내 코드는 다음과 같습니다.팬더 데이터 프레임 요소 내부의 배열에 '적용'사용

import pandas as pd 
import numpy as np 

def g(x): # Function fails if I omit the .tolist() 
    return (np.concatenate([x['B'][1:], x['C'][1:]])).tolist() 

df = pd.DataFrame({'A' : (1,2,3), \ 
        'B': (np.array([0,1,2,3]),np.array([3,4,5,6]),np.array([6,7,8,9])), \ 
        'C': (np.array([0,1,2,3]),np.array([2,9,6,9]),np.array([2,4,6,7]))}) 
# Before we start 
print(df) 
print("B is type: ", type(df.loc[0,'B'])) 
# First time 
df['G'] = df.apply(g, axis=1) 
print("G is type: ", type(df.loc[0,'G'])) 
# Second time 
df['H'] = df.apply(g, axis=1) 
print("H is type: ", type(df.loc[0,'H'])) 
# Third time 
df['I'] = df.apply(g, axis=1) 
print("I is type: ", type(df.loc[0,'I'])) 
# Fourth time - this one fails for me 
df['J'] = df.apply(g, axis=1) 
print("J is type: ", type(df.loc[0,'J'])) 
# Fifth time 
df['K'] = df.apply(g, axis=1) 
print("K is type: ", type(df.loc[0,'K'])) 

이 코드는 실패 할 때까지 df [ 'J'] 행까지 정상적으로 실행됩니다. 출력은 다음과 같다 :

A    B    C 
0 1 [0, 1, 2, 3] [0, 1, 2, 3] 
1 2 [3, 4, 5, 6] [2, 9, 6, 9] 
2 3 [6, 7, 8, 9] [2, 4, 6, 7] 
B is type: <class 'numpy.ndarray'> 
G is type: <class 'list'> 
H is type: <class 'list'> 
I is type: <class 'list'> 

그런 다음 "ValueError: Wrong number of items passed 6, placement implies 1"으로 완료 큰 긴 오류 메시지가, 거기에 너무 또한 "KeyError: 'J'"있다.

미친 문제는 함수가 처음 몇 번 제대로 실행된다는 것입니다. 내 질문 :

  • 왜 내 코드가 df['J']이되면 오류가 발생합니까?
  • g(x)을 목록이 아닌 numpy 배열로 반환하려면 어떻게해야합니까? .tolist()을 제외하면 오류가 발생합니다.
  • 데이터 프레임 요소 안에 배열을 사용하는 쉬운 방법이 있습니까?

아무런 도움이 대단히이 될 것입니다! 나는 여기에서 무슨 일이 일어나고 있는지 이해하려고 2 일을 보냈다.

P. 데이터 프레임 요소 안에 배열을 사용하는 이유를 설명하지는 않았지만 도움이된다고 생각한다면 설명 할 수 있습니다.

+1

코드가'J'에서 실패하는 이유는 6 열이되면 판다는 기존 열에'g' (길이가 6 인)의 결과를 맞추기 때문입니다. 그런 다음 6 열의 데이터 프레임을 반환하며이 열은 'J 열'에 맞지 않습니다. 'df.apply (g, axis = 1)'를'J '에 할당하기 직전에 시도해보십시오. – IanS

+1

@IanS 설명 주셔서 감사합니다, 나는 그것에 대해서도 고심하고있었습니다. 팬더는 이번에 어떻게 이전의 데이터 프레임으로 간주할까요? 이전에는 '시리즈'를 렌더링했지만 갑자기 '데이터 프레임'이됩니다. – ysearka

+1

@ysearka 나는 이것에 대해서도 고심하고 있었고 나는 정확한 설명을하지 못했다. 나는 팬더가 결과의 차원에 따라 추측을하는 것으로 추측하지만, 그렇지 않으면 강제로 수행하는 방법을 모르겠습니다. – IanS

답변

2

g 기능을 적용 할 때마다 데이터 프레임이 바뀌고 팬더의 반응이 매번 같지 않을 것입니다. 당신은 단지 열 BC에 적용해야하는 경우, 난 당신이 입력 제안 :

df['J'] = df[['B','C']].apply(g, axis=1) 
print("J is type: ", type(df.loc[0,'J'])) 

잘 작동이 방법 (그러나 다시 한번에만 열을 B 및 계정에 C).

오류에 대해서는 Ians에 따르면 응용 프로그램의 출력이 6 열 이상이되면 즉시 Series 대신 DataFrame이됩니다. 그런 다음 df['J']으로 설정할 수 없습니다.

+0

답변 해 주셔서 감사합니다. 나는 당신의 첫 번째 제안을 시도했는데, 다음과 같이 'B'와 'C'만 적용하면된다 :'df [ 'J'] = df [[ 'B', 'C']]. apply (g, axis = 1)'. 그리고 효과가있었습니다! @IanS가 준 이유 때문에 반환 된 시리즈의 요소 수가 더 이상 데이터 프레임의 열 수와 일치하지 않기 때문에 효과가 있다고 생각합니다. 그러나, 당신의 다른 제안, 편집, 나를 위해 작동하지 않았다. 이유를 모르겠다. 또한, 키 오류에 관해서는,이 줄이 실행되기 전에 실행이 이미 끝났다고 생각하기 때문에 원인이'df.loc [0, 'J'] '라고 생각하지 않습니다. – Michael

+0

@Michael 의견을 보내 주셔서 감사합니다. 답변을 정리합니다. – ysearka

+0

l @ ysearka, 나는 열의 수에 상관없이 작동하는 일반적인 솔루션을 누군가가 제공 할 수 있기를 희망하지만 도움을 주셔서 감사합니다. – Michael