1 目标 有两个DataFrame实例,分别为 df1, df2, 其中 col_id 是需要修正的列。修正的逻辑为,如果df1 和 df2 中都出现某个 col_id,则 df1对应的 st 列赋值为 1, 否则值不变。
2 多种实现
提供四种实现方法,有快有慢。尤其在处理千万级别的数据时,慢的写法要比快的慢上百倍之多。
下面一探究竟。
1def logic1(df1,df2):
2 for i,row in df1.iterrows():
3 sam = row['sku_id']
4 if len(df2[df2.loc[:,'col_id ']==sam])>0:
5 df1.loc[i,'st'] = 1
6
7
8def logic2(df1,df2):
9 s = set(df2.loc[:, 'col_id '])
10 for i,row in df1.iterrows():
11 if i%1000 == 0:
12 print(i)
13 sam = row['col_id ']
14 if sam in s:
15 df1.loc[i,'st'] = 1
16
17def logic3(df1,df2):
18 s = set(df2.loc[:, 'col_id '])
19 i = 0
20 sku_id_index = 5
21 for nt in df1.itertuples():
22 if i%1000==0:
23 print(i)
24 sam = nt[sku_id_index]
25 if sam in s:
26 df1.loc[i,'st'] = 1
27 i+=1
28
29def logic4(df1,df2):
30 mer = df1.merge(df2,on='sku_id',right_index=True)
31 df1.loc[mer.index,'st'] = 1
以上4种实现,在大数据量下测试过,实践表明:1最慢,2较慢,3很快,4最快。最慢的处理起来小时为单位,最快的不到1秒钟。
3 为什么
iterrows 尤其要慎用,这更多是一个坑,因为每次遍历,都会把 v 包装为一个 klass 对象,消耗时间。
1def iterrows(self):
2 columns = self.columns
3 klass = self._constructor_sliced
4 for k, v in zip(self.index, self.values):
5 s = klass(v, index=columns, name=k)
6 yield k, s
itertuples 建议用,因为它 Iterate over DataFrame rows as namedtuples,并且索引都是用 int index.
实现4告诉我们,能不用for就不用,尽量直接调用pandas的API,达到省掉for循环的目的,比如merge, 能高效实现两个及以上的DataFrame实例的关系操作。
本文分享自 程序员郭震zhenguo 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!