操作pandas数据帧值的有效方法



我正在处理两个巨大的数据帧,我需要执行一个特定的操作,为第一个数据帧中的每个唯一id检索两个数据帧之一的最频繁值。我将用一个例子来更好地解释它。

假设我必须使用数据帧,第一个将被称为df_id,第二个将被称作df_values

df_values:
ids values
0   id1 10
1   id2 20
2   id1 10
3   id1 30
4   id2 40
...
df_id:
ids desc
0   id1 a product
1   id2 a product
2   id3 a product

在实际的数据帧中,我有额外的列,但为了清晰起见,我省略了它们。

现在,df_id包含我需要的所有id的引用,而df_values包含与每个id相关的(多个(值。

我的工作范围是创建一个字典,为每个不同的id报告最频繁的值。如果它没有出现在df_values中,那么我会写一个None而不是一个值。

values_dict
{'id1': 10, 'id2': 20, 'id3': None}

我试图通过这样的方式来解决这个问题:

from collections import Counter
import numpy as np
def Most_Common(lst):
data = Counter(lst)
return data.most_common(1)[0][0]
dict_val = {}
for ar in pd.unique(df_id['ids']):
df_art = df_values.loc[df_values['ids'] == ar]
print("Done", ar)
val = Most_Common(df_art['values']) if not df_art.empty else None
dict_val[ar] = val

来自该应答的Most_Common函数的代码

然而,如果我的数据帧非常大,这个解决方案似乎不会很好地升级,这就是我的情况。我甚至尝试使用multiprocessing库:

from collections import Counter
import multiprocessing as mp
import numpy as np
dict_val = {}
unique_ids = pd.unique(df_id["ids"])
unique_ids = np.array_split(unique_ids, 5)
def register_value(ids):
for ar in ids:
df_art = df_values.loc[df_values['ids'] == ar]
print("Done", ar)
val = Most_Common(df_art['values']) if not df_art.empty else None
dict_val[ar] = val
with mp.Pool(processes = 5) as p:
p.map(register_value, unique_ids)

但代码仍在运行约40分钟。。。也许我做错了什么。是否有一种有效的解决方案,也可以应用于多处理的情况?非常感谢。

我的建议:

  1. 在按id分组的df_values中查找最频繁的值。如果有多个最频繁的值,则取第一个:

    most_freq = df_values.groupby('ids').agg(lambda x: pd.Series.mode(x)[0])['values'].to_dict()
    
  2. 从df_id中的id创建一个字典,并将None分配给每个索引:

    dict_val = dict.fromkeys(df_id['ids'])
    
  3. 用第一本词典更新第二本词典。所有"无"将替换为最频繁的值:

    dict_val.update(most_freq)
    

输出:

{'id1': 10, 'id2': 20, 'id3': None}

这只是一个样本,所以很难猜测它能在多大程度上提高性能。它应该更快,因为我们没有对所有元素进行迭代。请检查并告诉我。

相关内容

  • 没有找到相关文章

最新更新