programing

팬더 데이터 프레임 열에서 목록 길이를 결정하는 방법

newstyles 2023. 10. 1. 19:21

팬더 데이터 프레임 열에서 목록 길이를 결정하는 방법

열의 목록 길이를 반복하지 않고 어떻게 결정할 수 있습니까?

다음과 같은 데이터 프레임이 있습니다.

                                                    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
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대형 프레임용으로

res

위의 플롯을 생성하는 데 사용되는 코드:

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