Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.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 在一个数据帧上循环并从另一个数据帧获取相关数据:PANDAS_Python_Pandas - Fatal编程技术网

Python 在一个数据帧上循环并从另一个数据帧获取相关数据:PANDAS

Python 在一个数据帧上循环并从另一个数据帧获取相关数据:PANDAS,python,pandas,Python,Pandas,我有一个拥有客户所有交易数据的数据框架。列为mailid、txn_date、city。现在,我有一个情况,我必须考虑客户从01JAN2016和每一个邮件ID,我必须从基础文件获取他们的TXN数据,并考虑他们的最后12个月数据(TXN日期之间的最后TXN日期和-365天时间增量),然后找出他们的最大交易城市名称。 基本数据帧示例 #df maild txn_date city satya 2015-07-21 a satya 2015-08-11 b satya 2016-

我有一个拥有客户所有交易数据的数据框架。列为mailid、txn_date、city。现在,我有一个情况,我必须考虑客户从01JAN2016和每一个邮件ID,我必须从基础文件获取他们的TXN数据,并考虑他们的最后12个月数据(TXN日期之间的最后TXN日期和-365天时间增量),然后找出他们的最大交易城市名称。 基本数据帧示例

#df
maild   txn_date   city
satya   2015-07-21  a
satya   2015-08-11  b
satya   2016-05-11  c
xyz     2016-06-01  f
satya   2016-06-01  a
satya   2016-06-01  b
因为我需要2016-01-01的客户,所以我做了

d = df[['mailid', 'txn-date']][df['txn_date'] >= '2016-01-01']
现在,对于d中的每个mailid,我必须从基本数据帧df中获取它们最近12个月的每个事务数据,并计算它们的最大交易城市。为此,我使用了一个类似For的循环

x = d.groupby(['mailid'])['txn-date'].max().reset_index() #### finding their last transacted date to find out a 12 Month back date
x['max_city'] = 'N'  ## giving default value as 'N'
for idx,row in x.iterrows():
 g = row[1].date()
 h = g-timedelta(days=365)  ###getting the last 12 Month date 
 y = df[(df['mailid']==row[0]) & (df['txn_date'] >= str(h))]
 y.sort(['txn_date'],ascending=True,inplace=True)  ### sorting it bcoz i want to consider the last txn when count for one or more cities become same 
 c = y.groupby(['mailid','city']).size().reset_index()
 v = c.groupby(['mailid'])[0].max().reset_index()
 dca = pd.merge(y,c,on=['mailid','city'],how='left')
 dcb = pd.merge(dca,v,on=['mailid',0])
 m = dcb.drop_duplicates(['mailid'],take_last=True)
 row[2] = m['city'].unique()[0]
o/p:

虽然我的代码对小块数据有效(我确信它是无组织的,并且在我练习时没有使用正确的命名约定),但循环将针对dataFrame x中的每个客户命中主基本dataFrame df

所以我主要关心的是,我的df是否会有100Mln行,x是否会有6mln行。然后for循环将执行6Mln次,并点击df以获取匹配的mailid数据,并执行操作以查找最大交易城市

如果在1分钟内,它将计算3个mailid的最大城市。那么6百万分需要2百万分。。。这将是一个严重的问题

所以我需要你们的建议,如何优化这个场景……从而减少命中主基地的次数,并应用一些更方便的方法来实现这一点(我还不能做到)


请,建议!!!!感谢您的支持。

您可以更高效地使用groupby和应用功能

按city和maild分组,获取最大日期和交易总数。按最大日期排序

g=d.groupby(['maild','city'])['txn_date'].agg(['count','max']).sort_values('max',ascending=False)
然后通过邮件将其分组,并获得最高计数的索引

g.groupby(level='maild')['count'].agg(lambda x:pd.Series.argmax(x)[1])
-


顺便说一句,在你的例子中,你在2016-01-01有satya a和b的交易。您是如何决定b是正确答案的?

您可以更有效地使用groupby和应用功能

按city和maild分组,获取最大日期和交易总数。按最大日期排序

g=d.groupby(['maild','city'])['txn_date'].agg(['count','max']).sort_values('max',ascending=False)
然后通过邮件将其分组,并获得最高计数的索引

g.groupby(level='maild')['count'].agg(lambda x:pd.Series.argmax(x)[1])
-


顺便说一句,在你的例子中,你在2016-01-01有satya a和b的交易。您是如何决定b是正确答案的?

这里有一个可能更容易阅读的替代方案:

def f(g):
    dc=g.groupby('city')['txn_date']
    dc_sorted=dc.agg(['count','max']).sort_values('max',ascending=False)
    return dc_sorted['count'].argmax()

d.groupby(['maild']).apply(f)

但是,我怀疑
apply
在非常大的表上会有一些性能问题。

这里有一个可能更容易阅读的替代方案:

def f(g):
    dc=g.groupby('city')['txn_date']
    dc_sorted=dc.agg(['count','max']).sort_values('max',ascending=False)
    return dc_sorted['count'].argmax()

d.groupby(['maild']).apply(f)

但是,我怀疑
apply
在非常大的表上会有一些性能问题。

考虑
apply
transform
函数。第一个运行组根据时间范围对
maild
city
进行计数,第二个运行组通过
maild
最大化计数。最后,末尾的
groupby()
过滤将保留计数等于max count的对

def last12mos(row):
    row['count'] = 0
    row.loc[row['txn_date'] >= row['txn_date'].max() - timedelta(days=365), 'count'] = 1
    row['count'] = row['count'].sum()
    return(row)

basedf = basedf.groupby(['maild', 'city']).apply(last12mos)    
basedf['maxcount'] = basedf.groupby(['maild'])['count'].transform(max)

finaldf = basedf[basedf['count'] == basedf['maxcount']].\
                                            groupby(['maild', 'city']).aggregate(max)

考虑一个
apply
transform
函数。第一个运行组根据时间范围对
maild
city
进行计数,第二个运行组通过
maild
最大化计数。最后,末尾的
groupby()
过滤将保留计数等于max count的对

def last12mos(row):
    row['count'] = 0
    row.loc[row['txn_date'] >= row['txn_date'].max() - timedelta(days=365), 'count'] = 1
    row['count'] = row['count'].sum()
    return(row)

basedf = basedf.groupby(['maild', 'city']).apply(last12mos)    
basedf['maxcount'] = basedf.groupby(['maild'])['count'].transform(max)

finaldf = basedf[basedf['count'] == basedf['maxcount']].\
                                            groupby(['maild', 'city']).aggregate(max)

城市是一个文本列,是否要聚合最大交易城市名称?你是说城市的最大值吗?还是字母顺序最高的城市?@完全是冻糕!!!我想要城市数量的最大值,或者你可以说最喜欢的城市…城市是一个文本列,你想聚合最大交易城市名称?你是说城市的最大值吗?还是字母顺序最高的城市?@完全是冻糕!!!我想要Max的城市统计,或者你可以说最喜欢的城市……维克多,你的建议在整个数据文件上都很好,但是我有另一个条件,比如,对于每一个邮件ID,我必须考虑到最后的12个月的交易……那么,如何在你的代码中符合这个条件呢?例如,如果“satya”说有另一个txn日期“2014-02-01”,则不应将其视为最后一个txn日期“2016-06-01”,365天的增量为“2015-06-01”。。。因此,ia也必须实现这种情况。你能帮忙吗!!!看来,你可以先过滤整个数据集来排除少于12个月前的所有东西。@维克多,你的建议在整个数据文件上都很好,但是我有另一个条件,比如,对于每一个邮件ID,我必须考虑到最后的12个月的交易……那么,如何在代码中拟合这个条件呢?例如,如果“satya”说有另一个txn日期“2014-02-01”,则不应将其视为最后一个txn日期“2016-06-01”,365天的增量为“2015-06-01”。。。因此,ia也必须实现这种情况。你能帮忙吗!!!看起来您可以先过滤整个数据集,以排除12个月前的所有内容?