gpt4 book ai didi

python - 使用 NaN 获得 Pandas 系列模式的最快方法

转载 作者:行者123 更新时间:2023-12-04 10:15:01 24 4
gpt4 key购买 nike

我需要找到 pandas groupby 对象或单个系列的模式/最常见元素,为此我具有以下功能:

def get_most_common(srs):
from collections import Counter
import numpy as np

x = list(srs)
my_counter = Counter(x)
if np.nan not in my_counter.keys():
most_common_value = my_counter.most_common(1)[0][0]
else:
most_common_value = srs.mode(dropna=False).iloc[0]

return most_common_value

在平局的情况下,我不在乎选择哪一个——随机就可以了。
Counter当没有 NaN 时速度更快,但使用 NaN 时会给出错误的结果。 pd.Series.mode总是正确的,但比 Counter 慢当没有 NaN 时。这是一场赌博(由于额外的检查 np.nan not in my_counter.keys() ,在没有 NaN 时更快,但在有 NaN 时更慢)。到目前为止,我的大型数据集的性能令人满意,可能是因为很多情况下没有 NaN。但是有没有办法让这更快?

最佳答案

我觉得奇怪的是您使用 Counter 获得了更好的性能.这是我的测试结果(n=10000):

Using Series.mode on Series with nan: 52.41649858
Using Series.mode on Series without nan: 17.186453438
Using Counter on Series with nan: 269.33117825500005
Using Counter on Series without nan: 134.207576572

#-----------------------------------------------------#

Series.mode Counter
----------- -------------
With nan 52.42s 269.33s
Without nan 17.19s 134.21s

测试代码:
import timeit

setup = '''
import pandas as pd
from collections import Counter

def get_most_common(srs):
return srs.mode(dropna=False)[0]

def get_most_common_counter(srs):
x = list(srs)
my_counter = Counter(x)
return my_counter.most_common(1)[0][0]

df = pd.read_csv(r'large.data')
'''

print(f"""Using Series.mode on Series with nan: {timeit.timeit('get_most_common(df["has_nan"])', setup=setup, number=10000)}""")
print(f"""Using Series.mode on Series without nan: {timeit.timeit('get_most_common(df["no_nan"])', setup=setup, number=10000)}""")
print(f"""Using Counter on Series with nan: {timeit.timeit('get_most_common_counter(df["has_nan"])', setup=setup, number=10000)}""")
print(f"""Using Counter on Series without nan: {timeit.timeit('get_most_common_counter(df["no_nan"])', setup=setup, number=10000)}""")
large.data是 2 x 50000 行 DataFrame来自 0 的随机 2 位字符串至 99 , 其中 has_nan有一个 modenan=551 .

如果有的话,您的 if np.nan not in my_counter.keys()条件总是会被触发,因为 np.nan不在 my_counter.keys() 中.所以实际上你从未使用过 pd.Series.mode , 它总是使用 Counter .如另一个问题所述,因为您的 pandas对象已创建 np.nan 的副本在 Series/DataFrame 内, in条件永远不会满足。试试看:
np.nan in pd.Series([np.nan, 1, 2]).to_list()
# False

删除 if/else 的全部复杂性并坚持一种方法。然后比较性能。正如您在另一个问题中提到的, Pandas 方法几乎总是比任何外部模块/方法更好的方法。如果您仍在观察其他情况,请更新您的问题。

关于python - 使用 NaN 获得 Pandas 系列模式的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61105953/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com