팬더 데이터 프레임 열에서 목록 길이를 결정하는 방법
열의 목록 길이를 반복하지 않고 어떻게 결정할 수 있습니까?
다음과 같은 데이터 프레임이 있습니다.
CreationDate
2013-12-22 15:25:02 [ubuntu, mac-osx, syslinux]
2009-12-14 14:29:32 [ubuntu, mod-rewrite, laconica, apache-2.2]
2013-12-22 15:42:00 [ubuntu, nat, squid, mikrotik]
목록의 길이를 계산하고 있습니다.CreationDate
칼럼과 새것 만들기Length
다음과 같은 열:
df['Length'] = df.CreationDate.apply(lambda x: len(x))
그래서 저는 이렇게 생각합니다.
CreationDate Length
2013-12-22 15:25:02 [ubuntu, mac-osx, syslinux] 3
2009-12-14 14:29:32 [ubuntu, mod-rewrite, laconica, apache-2.2] 4
2013-12-22 15:42:00 [ubuntu, nat, squid, mikrotik] 4
이것을 할 더 많은 피톤적인 방법이 있습니까?
사용할 수 있습니다.str
일부 목록 작업을 위한 접근자도 있습니다.이 예에서,
df['CreationDate'].str.len()
각 목록의 길이를 반환합니다.에 대한 문서를 참조하십시오.
df['Length'] = df['CreationDate'].str.len()
df
Out:
CreationDate Length
2013-12-22 15:25:02 [ubuntu, mac-osx, syslinux] 3
2009-12-14 14:29:32 [ubuntu, mod-rewrite, laconica, apache-2.2] 4
2013-12-22 15:42:00 [ubuntu, nat, squid, mikrotik] 4
이러한 작업의 경우 바닐라 파이썬이 일반적으로 더 빠릅니다. 팬더는 NaN을 처리합니다.시간은 다음과 같습니다.
ser = pd.Series([random.sample(string.ascii_letters,
random.randint(1, 20)) for _ in range(10**6)])
%timeit ser.apply(lambda x: len(x))
1 loop, best of 3: 425 ms per loop
%timeit ser.str.len()
1 loop, best of 3: 248 ms per loop
%timeit [len(x) for x in ser]
10 loops, best of 3: 84 ms per loop
%timeit pd.Series([len(x) for x in ser], index=ser.index)
1 loop, best of 3: 236 ms per loop
pandas.Series.map(len)
그리고.pandas.Series.apply(len)
실행 시간이 동일하며, 보다 약간 빠릅니다.pandas.Series.str.len()
.
import pandas as pd
data = {'os': [['ubuntu', 'mac-osx', 'syslinux'], ['ubuntu', 'mod-rewrite', 'laconica', 'apache-2.2'], ['ubuntu', 'nat', 'squid', 'mikrotik']]}
index = ['2013-12-22 15:25:02', '2009-12-14 14:29:32', '2013-12-22 15:42:00']
df = pd.DataFrame(data, index)
# create Length column
df['Length'] = df.os.map(len)
# display(df)
os Length
2013-12-22 15:25:02 [ubuntu, mac-osx, syslinux] 3
2009-12-14 14:29:32 [ubuntu, mod-rewrite, laconica, apache-2.2] 4
2013-12-22 15:42:00 [ubuntu, nat, squid, mikrotik] 4
%timeit
import pandas as pd
import random
import string
random.seed(365)
ser = pd.Series([random.sample(string.ascii_letters, random.randint(1, 20)) for _ in range(10**6)])
%timeit ser.str.len()
252 ms ± 12.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit ser.map(len)
220 ms ± 7.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit ser.apply(len)
222 ms ± 8.31 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
목록으로 변환 및map
함수
팬더 데이터프레임 열은 목록, 튜플 등의 컬렉션을 저장하기 위한 것이 아닙니다. 이는 사실상 이러한 열에서 최적화된 방법이 작동하지 않기 때문입니다. 따라서 데이터프레임에 이러한 항목이 포함되어 있는 경우 일반적으로 열을 파이썬 목록으로 변환하여 목록을 조작하는 것이 더 효율적입니다.
또한, 만약 함수(특히 내장된 함수)가 있다면,len()
목록의 각 항목을 호출해야 합니다. 일반적으로 다음을 수행하는 것이 더 빠릅니다.map
이 함수를 순환 함수로 부르기 보다는
mylist = df['CreationDate'].tolist()
df['Length'] = list(map(len, mylist))
처리 NaNs
좋은 점은str.len()
NaNs를 처리하지만 사용자 지정 기능은try-except
그 공백을 메울 수 있을 겁니다.
def nanlen(x):
try:
return len(x)
except TypeError:
return float('nan')
df['Length'] = list(map(nanlen, mylist))
런타임 벤치마크
기본적으로 지도제작은len
오버 리스트는 시리즈를 루프하는 것보다 약 2.5배 빠르며, 이는 다시 2.5배 빠릅니다.pd.Series.str.len
대형 프레임용으로
위의 플롯을 생성하는 데 사용되는 코드:
import pandas as pd
import random, string, perfplot
random.seed(365)
perfplot.plot(
setup=lambda n: pd.Series([random.sample(string.ascii_letters, random.randint(1, 20)) for _ in range(n)]),
kernels=[lambda ser: ser.str.len(), lambda ser: ser.map(len), lambda ser: list(map(len, ser.tolist())), lambda ser: [len(x) for x in ser]],
labels=["ser.str.len()", "ser.map(len)", "list(map(len, ser.tolist()))", "[len(x) for x in ser]"],
n_range=[2**k for k in range(21)],
xlabel='Length of dataframe',
equality_check=lambda x,y: x.eq(y).all()
)
언급URL : https://stackoverflow.com/questions/41340341/how-to-determine-the-length-of-lists-in-a-pandas-dataframe-column
'programing' 카테고리의 다른 글
함수 포인터가 명령 파이프라인을 삭제하도록 강제합니까? (0) | 2023.10.06 |
---|---|
MariaDB의 COLUMN_ADD 함수에 해당하는 PHP 또는 MySQL 찾기 (0) | 2023.10.01 |
cmd.exe 및 PowerShell에서 PROPMENT(PROPMENT만 해당)의 색상은? (0) | 2023.10.01 |
중앙 이미지(가로로 div) (0) | 2023.10.01 |
각도 7 테스트: Null Injector 오류: 활성화된 경로에 대한 공급자 없음 (0) | 2023.10.01 |