【问题标题】:How to apply a function to sub selections in a pandas DataFrame object efficiently?如何有效地将函数应用于熊猫 DataFrame 对象中的子选择?
【发布时间】:2022-01-10 15:20:00
【问题描述】:

我有一个包含人们地址和姓名的数据框。我有一个处理我想要应用的名称的函数。我正在创建具有匹配地址的人员的子选择并将该功能应用于这些组。

至此我一直使用.loc如下

for x in df['address'].unique():
   sub_selection = df.loc[df['address'] == x]
   sub_selection.apply(lambda x: function(x), axis = 1)

有没有更有效的方法来解决这个问题。我正在研究 pandas .groupby() 功能,但我正在努力让它工作。

df.groupby('address').agg(lambda x: function(x['names']))

这是一些示例数据:

address, name, Unique_ID

1022 Boogie Woogie Ave, John Smith, np.nan
1022 Boogie Woogie Ave, Frederick Smith, np.nan
1022 Boogie Woogie Ave, John Jacob Smith, np.nan
3030 Sesame Street, Big Bird, np.nan
3030 Sesame Street, Elmo, np.nan
3030 Sesame Street, Big Yellow Bird, np.nan

我的函数本身有一些移动部分,但基本上我会根据我创建的参考字典检查名称。此过程会通过其他一些步骤,但会返回名称匹配的索引列表。我使用这些索引为匹配的名称分配一个共享的唯一 ID。在我的示例中,大鸟和大黄鸟会匹配。

def function(x):
    match_list = []
    if x['name'] in __lookup_dict[0]:
        match_list.append((__lookup_dict[0][x['name']))
    #reduce all elements matching list to a single list of place ids matching all elements
    result = set(match_list[0])
    for s in match_list[1:]:
        if len(result.intersection(s)) != 0:
            result.intersection_update(s)
    #take the reduce lists and assign each place id an unique id. 
    #note we are working with place ids not the sub df's index. They don't match
    if pd.isnull(x['Unique_ID']):
        uid = str(uuid.uuid4())
        for g in result:
            df.at[df.index[df.index == g].tolist()[0], 'Unq_ID'] = uid
    else:
        pass
    return result

【问题讨论】:

  • 你能分享一下什么不起作用的细节吗?一些示例数据也会有所帮助!
  • 当然,我正在努力将一个函数传递给 groupby 对象,以便在所有子选择上独立运行该函数。我发布的初始功能有效,但速度很慢,而且我正在处理数百万条记录的数据集。该功能的基础是匹配人们的姓名,我只关心人们共享相同地址的姓名。所以特别是 groupby 函数,它似乎只接受向量化函数(我在这里可能错了),我的函数并不意味着向量化。所以函数本身并没有传递给对象
  • 知道了,谢谢!我真的需要看到一个独立的、可运行的示例,包括数据和function 的定义。
  • 我已经附加了这个问题。我试图将功能简化为相关步骤。如果有任何不清楚的地方,请告诉我

标签: python pandas performance pandas-groupby


【解决方案1】:

尝试使用

df.groupby('address').apply(lambda x: function(x['names']))

已编辑: 检查这个例子。我使用了另一个 StackOverflow 问题中的数据框

import pandas as pd 

df = pd.DataFrame({
    "City":["Delhi","Delhi","Mumbai","Mumbai","Lahore","Lahore"],
    "Points":[90.1,90.3,94.1,95,89,90.5],
    "Gender":["Male","Female","Female","Male","Female","Male"]
})

d = {k:v for v,k in enumerate(df.City.unique())}
df['idx'] = df['City'].replace(d)
print(df)

输出:

     City  Points  Gender  idx
0   Delhi    90.1    Male    0
1   Delhi    90.3  Female    0
2  Mumbai    94.1  Female    1
3  Mumbai    95.0    Male    1
4  Lahore    89.0  Female    2
5  Lahore    90.5    Male    2

所以,尝试使用

d = {k:v for v,k in enumerate(df['address'].unique())}
df['idx'] = df['address'].replace(d)

【讨论】:

  • 当我运行它时,我得到以下信息: TypeError: () got an unexpected keyword argument 'axis'。我不 groupby 对象正在接受 .apply 方法
  • 我删除了axis。你能具体说明function 的作用吗?
  • 是的,该函数通过一系列处理步骤匹配名称,并为匹配的名称分配一个唯一的 id。因为我只关心匹配具有相同地址的名称,所以我只想处理子地址选择中的名称。因为该函数需要迭代运行,所以我需要与 axis =1 参数相同的功能。无论如何,当我尝试将调用特定字段名称的函数传递给 groupby 对象时,它不会读取字段名称。例如,它不会读取所有者的姓名字段,这是我的函数的参数。
  • 所以我认为我只是错误地使用了这个 groupby 对象
  • @Vance 我已经根据任务编辑了答案。我希望我做对了
猜你喜欢
  • 2016-08-18
  • 1970-01-01
  • 2017-01-20
  • 1970-01-01
  • 1970-01-01
  • 2021-11-20
  • 2019-09-02
  • 2018-04-21
  • 2012-11-14
相关资源
最近更新 更多