programing

팬더 데이터 프레임을 신청하기 위해 람다를 전달하는 데 문제가 있음

codeshow 2023. 9. 24. 13:10
반응형

팬더 데이터 프레임을 신청하기 위해 람다를 전달하는 데 문제가 있음

팬더 DataFrame의 모든 행에 함수를 적용하려고 합니다(실제로 해당 DataFrame에서 한 열만 있음).

이것은 구문 오류라고 확신하지만 내가 무엇을 잘못하고 있는지 확신합니다.

df['col'].apply(lambda x, y:(x - y).total_seconds(), args=[d1], axis=1)

col열은 많은 a를 포함합니다.datetime.datetime물건들과d1그들 중 가장 초기의 것입니다.각 행에 대한 총 초수의 열을 구하려고 합니다.

다음 오류가 계속 발생합니다.

TypeError: <lambda>() got an unexpected keyword argument 'axis'

나는 왜 그런지 이해하지 않아요.axis내게 전해지고 있습니다.lambda기능.

저도 해봤어요.

def diff_dates(d1, d2):
    return (d1-d2).total_seconds()

df['col'].apply(diff_dates, args=[d1], axis=1)

그리고 저도 같은 오류를 받습니다.

통화와 별개로 통화에 대한 매개변수는 없습니다.

Series.apply(func, convert_dtype=)사실, args= (), **kwds)

func : function
convert_dtype : boolean, default True
Try to find better dtype for elementwise function results. If False, leave as dtype=object
args : tuple
Positional arguments to pass to function in addition to the value

df용이 있지만 시리즈로 호출할 때 어떻게 작동할 것으로 예상하는지는 불확실하지만 연속으로 작동할 것으로 예상합니까?

하나의 열은 (보통) 팬더 시리즈이고, 에드첨이 언급했듯이,DataFrame.apply가지다axis논쟁은 하지만Series.apply안 해봤어요, 그래서apply위에axis=1기둥에서 작동하지 않습니다.

다음이 작동합니다.

df['col'].apply(lambda x, y: (x - y).total_seconds(), args=(d1,))

각 요소에 대한 함수를 연속으로 적용할 경우,map다음과 같이 사용할 수도 있습니다.

df['col'].map(lambda x: (x - d1).total_seconds())

~하듯이apply파이썬 루프에 대한 통사적 설탕일 뿐인데, 팬더가 머리 위에 있지 않기 때문에 목록 이해가 둘 다보다 더 효율적일 수 있습니다.

[(x - d1).total_seconds() for x in df['col'].tolist()]

단일 열 DataFrame의 경우,axis=1다음을 전달할 수 있습니다.

df[['col']].apply(lambda x, y: (x - y).dt.total_seconds(), args=[d1], axis=1)

PSA: 피합니다.apply네가 할 수 있으면.

apply대부분의 경우 필요하지도 않습니다.OP의 경우(그리고 대부분의 다른 경우), 벡터화된 연산이 존재합니다(단, 빼기만 함).d1from column - 값은 column)과 일치하도록 브로드캐스트되며 보다 훨씬 빠릅니다.apply어쨌든:

(df['col'] - d1).dt.total_seconds()

타이밍

벡터화된 뺄셈은 약 150배 빠릅니다.apply보다 7000배 이상 빠른 열에apply단일 열에 데이터프레임 10k 행의 프레임에 대한 데이터프레임. As.apply는 루프입니다. 이 간격은 행의 수가 증가할수록 커집니다.

df = pd.DataFrame({'col': pd.date_range('2000', '2023', 10_000)})
d1 = df['col'].min()

%timeit df['col'].apply(lambda x, y: (x - y).total_seconds(), args=[d1])
# 124 ms ± 7.57 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit df['col'].map(lambda x: (x - d1).total_seconds())
# 127 ms ± 16.8 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit [(x - d1).total_seconds() for x in df['col'].tolist()]
# 107 ms ± 4.14 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit (df['col'] - d1).dt.total_seconds()
# 851 µs ± 189 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

%timeit df[['col']].apply(lambda x, y: (x - y).dt.total_seconds(), args=[d1], axis=1)
# 6.07 s ± 419 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

언급URL : https://stackoverflow.com/questions/29155310/trouble-passing-in-lambda-to-apply-for-pandas-dataframe

반응형