[python] Pandas 데이터 프레임의 두 열에 함수를 적용하는 방법

df열 이있는 것으로 가정하십시오 'ID', 'col_1', 'col_2'. 그리고 함수를 정의합니다.

f = lambda x, y : my_function_expression.

이제 fto df의 두 열 'col_1', 'col_2'을 요소별로 적용하여 새 열 을 요소별로 계산하려고합니다 'col_3'.

df['col_3'] = df[['col_1','col_2']].apply(f)
# Pandas gives : TypeError: ('<lambda>() takes exactly 2 arguments (1 given)'

수행하는 방법 ?

** 아래와 같이 상세 샘플 추가 ***

import pandas as pd

df = pd.DataFrame({'ID':['1','2','3'], 'col_1': [0,2,3], 'col_2':[1,4,5]})
mylist = ['a','b','c','d','e','f']

def get_sublist(sta,end):
    return mylist[sta:end+1]

#df['col_3'] = df[['col_1','col_2']].apply(get_sublist,axis=1)
# expect above to output df as below 

  ID  col_1  col_2            col_3
0  1      0      1       ['a', 'b']
1  2      2      4  ['c', 'd', 'e']
2  3      3      5  ['d', 'e', 'f']



답변

다음 apply은 데이터 프레임에서 사용하는 예제 입니다 axis = 1.

차이점은 두 값을 함수에 전달하는 대신 fpandas Series 객체를 허용하도록 함수를 다시 작성한 다음 Series를 인덱싱하여 필요한 값을 얻는다는 점입니다.

In [49]: df
Out[49]:
          0         1
0  1.000000  0.000000
1 -0.494375  0.570994
2  1.000000  0.000000
3  1.876360 -0.229738
4  1.000000  0.000000

In [50]: def f(x):
   ....:  return x[0] + x[1]
   ....:

In [51]: df.apply(f, axis=1) #passes a Series object, row-wise
Out[51]:
0    1.000000
1    0.076619
2    1.000000
3    1.646622
4    1.000000

사용 사례에 따라 팬더 group객체를 만든 다음 apply그룹에서 사용 하는 것이 도움이되는 경우가 있습니다 .


답변

Pandas에는 한 줄로 깔끔하게 정리할 수 있습니다.

df['col_3'] = df.apply(lambda x: f(x.col_1, x.col_2), axis=1)

이를 통해 f여러 입력 값을 가진 사용자 정의 함수가 가능하고 (안전하지 않은) 숫자 인덱스 대신 (안전한) 열 이름을 사용하여 열에 액세스합니다.

데이터가있는 예 (원래 질문을 기반으로 함) :

import pandas as pd

df = pd.DataFrame({'ID':['1', '2', '3'], 'col_1': [0, 2, 3], 'col_2':[1, 4, 5]})
mylist = ['a', 'b', 'c', 'd', 'e', 'f']

def get_sublist(sta,end):
    return mylist[sta:end+1]

df['col_3'] = df.apply(lambda x: get_sublist(x.col_1, x.col_2), axis=1)

출력 print(df):

  ID  col_1  col_2      col_3
0  1      0      1     [a, b]
1  2      2      4  [c, d, e]
2  3      3      5  [d, e, f]

열 이름에 공백이 있거나 기존 데이터 프레임 속성과 이름을 공유하는 경우 대괄호로 색인을 생성 할 수 있습니다.

df['col_3'] = df.apply(lambda x: f(x['col 1'], x['col 2']), axis=1)


답변

간단한 해결책은 다음과 같습니다.

df['col_3'] = df[['col_1','col_2']].apply(lambda x: f(*x), axis=1)


답변

흥미로운 질문입니다! 내 대답은 아래와 같습니다.

import pandas as pd

def sublst(row):
    return lst[row['J1']:row['J2']]

df = pd.DataFrame({'ID':['1','2','3'], 'J1': [0,2,3], 'J2':[1,4,5]})
print df
lst = ['a','b','c','d','e','f']

df['J3'] = df.apply(sublst,axis=1)
print df

산출:

  ID  J1  J2
0  1   0   1
1  2   2   4
2  3   3   5
  ID  J1  J2      J3
0  1   0   1     [a]
1  2   2   4  [c, d]
2  3   3   5  [d, e]

ID <J1 <J2 <J3을 보장하기 위해 열 이름을 ID, J1, J2, J3으로 변경하여 열이 올바른 순서로 표시됩니다.

하나 더 간단한 버전 :

import pandas as pd

df = pd.DataFrame({'ID':['1','2','3'], 'J1': [0,2,3], 'J2':[1,4,5]})
print df
lst = ['a','b','c','d','e','f']

df['J3'] = df.apply(lambda row:lst[row['J1']:row['J2']],axis=1)
print df


답변

찾고있는 방법은 Series.combine입니다. 그러나 데이터 유형에 대해서는 약간의주의가 필요합니다. 귀하의 예에서 (응답을 테스트 할 때와 마찬가지로) 순진하게 전화하십시오.

df['col_3'] = df.col_1.combine(df.col_2, func=get_sublist)

그러나 이것은 오류를 발생시킵니다.

ValueError: setting an array element with a sequence.

가장 좋은 추측은 결과가 메소드를 호출하는 시리즈와 동일한 유형 일 것으로 예상되는 것 같습니다 (df.col_1 here). 그러나 다음과 같이 작동합니다.

df['col_3'] = df.col_1.astype(object).combine(df.col_2, func=get_sublist)

df

   ID   col_1   col_2   col_3
0   1   0   1   [a, b]
1   2   2   4   [c, d, e]
2   3   3   5   [d, e, f]


답변

당신이 쓴 방식에는 두 개의 입력이 필요합니다. 오류 메시지를 보면 f에 두 개의 입력을 제공하지 않고 하나만 제공한다고 표시됩니다. 오류 메시지가 정확합니다.
불일치는 df [[ ‘col1’, ‘col2’]]가 두 개의 개별 열이 아닌 두 개의 열이있는 단일 데이터 프레임을 반환하기 때문입니다.

단일 입력을 취하도록 f를 변경하고 위의 데이터 프레임을 입력으로 유지 한 다음 함수 본문 에서 x, y로 나눕니다 . 그런 다음 필요한 것을 수행하고 단일 값을 반환하십시오.

구문은 .apply (f)이므로이 함수 서명이 필요합니다. f는 현재 f가 기대하는 두 가지가 아니라 단일 것 = 데이터 프레임을 가져와야합니다.

f의 본문을 제공하지 않았으므로 더 이상 도움을 줄 수는 없지만 기본적으로 코드를 변경하거나 적용하지 않고 다른 방법을 사용하지 않고 탈출구를 제공해야합니다.


답변

np.vectorize에 대한 투표를하겠습니다. 그것은 x 개의 열을 넘어서서 함수의 데이터 프레임을 처리하지 않아도되므로 2 개의 열과 상수를 함수로 보내는 것과 같이 제어하거나 수행하지 않는 함수 (예 : col_1, col_2, ‘foo’).

import numpy as np
import pandas as pd

df = pd.DataFrame({'ID':['1','2','3'], 'col_1': [0,2,3], 'col_2':[1,4,5]})
mylist = ['a','b','c','d','e','f']

def get_sublist(sta,end):
    return mylist[sta:end+1]

#df['col_3'] = df[['col_1','col_2']].apply(get_sublist,axis=1)
# expect above to output df as below 

df.loc[:,'col_3'] = np.vectorize(get_sublist, otypes=["O"]) (df['col_1'], df['col_2'])


df

ID  col_1   col_2   col_3
0   1   0   1   [a, b]
1   2   2   4   [c, d, e]
2   3   3   5   [d, e, f]