Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何有效地将数据框中的条目映射到字典_Python_Python 3.x_Dictionary_Optimization_Pandas - Fatal编程技术网

Python 如何有效地将数据框中的条目映射到字典

Python 如何有效地将数据框中的条目映射到字典,python,python-3.x,dictionary,optimization,pandas,Python,Python 3.x,Dictionary,Optimization,Pandas,很长一段时间以来,我一直是stackoverflow的粉丝,我发现它非常有用。然而,这次我觉得有必要问一个关于我所写代码的性能相关问题,我希望我能从社区得到一些有价值的帮助 我的问题涉及在“用户”数据框(见下文)中向给定用户推荐广告的问题,其中“adids”数据框中的每个广告必须满足某些标准才能推荐给用户。数据在以下表格中: users = pd.DataFrame({"loginid" : [0, 0, 0, 1, 1, 0], "min_price" :

很长一段时间以来,我一直是stackoverflow的粉丝,我发现它非常有用。然而,这次我觉得有必要问一个关于我所写代码的性能相关问题,我希望我能从社区得到一些有价值的帮助

我的问题涉及在“用户”数据框(见下文)中向给定用户推荐广告的问题,其中“adids”数据框中的每个广告必须满足某些标准才能推荐给用户。数据在以下表格中:

users = pd.DataFrame({"loginid" : [0, 0, 0, 1, 1, 0], 
                  "min_price" : [10, 10, 10, 20, 20, 10], 
                  "max_price" : [30, 30, 30, 40, 40, 30], 
                  "municipal" : ["a", "b", "c", "d", "e", "e"] })
ads数据框如下所示:

adids = pd.DataFrame({"adid" : [100, 101, 102, 103, 104, 105], 
                  "totalprice" : [11., 15, 15, 25, 35, 25], 
                  "municipal" : ["a", "a", "d", "d", "e", "d"]})
我想要(有效地)实现的是对给定用户(即给定loginid)的相关广告进行过滤。目前,我正在填充一个名为“adsdict”的字典,其中键是用户的loginid,值都是推荐的adid。如果“totalprice”介于用户的最大和最小价格范围(由“min_price”和“max_price”给出)之间,并且用户在市政方面也有匹配项,则建议使用广告。下面的代码实现了这一点,但是,我不确定我这样做的效率有多高。在我的完整数据集上,这是一个非常大的数据集(10^6++行的顺序),当涉及到时间消耗时,这部分绝对是我的瓶颈

adsdict = {}

unique_logins = np.unique(users.loginid)
for logid in unique_logins:
    row_indexer = (users.loginid == logid)
    user = users[row_indexer]
    max_price = user.ix[row_indexer, "max_price"].max()
    min_price = user.ix[row_indexer, "min_price"].min()
    row_indexer_2 = (adids.totalprice >= min_price) \
                                & (adids.totalprice <= max_price)    
    ads = adids.loc[row_indexer_2, ["adid", "municipal"]]
    adsdict[logid] = list( pd.merge(user, ads, on="municipal").adid.values )
这是理想的结果。然而,正如前面所指定的,我担心我的编码方式是低效的,因为我必须为每个loginid执行连接操作

如果更有经验的python用户(我正在使用Python3.4和pandas 0.16.2)能够就如何优化这一点提供建议,我将不胜感激。我对各种(快速!)解决方案都持开放态度,但内存也是一个因素(尽管我可以访问内存丰富的服务器,所以这不是目前最关键的问题。)因此,解决方案甚至不需要使用字典,我唯一的标准是能够看到向给定用户推荐了哪些广告(loginid)

提前谢谢

问候,

马格纳斯


另外,当我在这里发布queston时,我已经尝试过遵守最佳实践。如果我忽略了提供必要的信息,我提前表示歉意。

因此,首先您需要从
广告
中找到匹配
市政
用户,您可以通过合并两个帧来实现这一点,这就是您满足第一个条件的方式

In [15]:
match_minicipal_df = pd.merge(users , adids , on = 'municipal')
match_minicipal_df
Out[15]:
loginid    max_price    min_price   municipal   adid    totalprice
0               30          10          a       100         11
0               30          10          a       101         15
1               40          20          d       102         15
1               40          20          d       103         25
1               40          20          d       105         25
1               40          20          e       104         35
0               30          10          e       104         35
然后,为了满足第二个条件,即
总计
应介于
最小值
最大值
之间,您可以通过

In [32]:
match = np.logical_and(match_minicipal_df.totalprice > match_minicipal_df.min_price , match_minicipal_df.totalprice < match_minicipal_df.max_price)
match
Out[32]:
0     True
1     True
2    False
3     True
4     True
5     True
6    False
dtype: bool
正如你在这里看到的

In [53]:
match_minicipal_df.ix[match ,['loginid' , 'adid'] ]
Out[53]:
loginid adid
0       100
0       101
1       103
1       105
1       104

非常感谢良信电器,非常感谢。答案也很快。
In [33]:
match_minicipal_df[match]
Out[33]:
loginid max_price     min_price municipal   adid    totalprice
0           30              10      a       100         11
0           30              10      a       101         15
1           40              20      d       103         25
1           40              20      d       105         25
1           40              20      e       104         35
In [53]:
match_minicipal_df.ix[match ,['loginid' , 'adid'] ]
Out[53]:
loginid adid
0       100
0       101
1       103
1       105
1       104