【发布时间】:2020-04-18 12:29:45
【问题描述】:
如何避免for index, row in df.iterrows()?
我的数据是这样的:
import pandas as pd
keys = ['Address', 'CoordinateX', 'CoordinateY']
values = [['Addr1', 'Addr2', 'Addr3'], [0, 1, 1], [9, 2, 1]]
addresses = dict(zip(keys, values))
df = pd.DataFrame(addresses, columns=keys)
R = 1
df 可以显示为:
Address CoordinateX CoordinateY
0 Addr1 0 9
1 Addr2 1 2
2 Addr3 1 1
我的任务是添加一个新列Counts,它存储位于同一区域内的地址数量 - 一定半径的圆R。但是,在最终数据帧上,我只希望每个区域有一个代表地址。所以计算后的输出是:
Address CoordinateX CoordinateY Counts
0 Addr1 0 9 1
1 Addr2 1 2 2
最初,我有这个代码:
df_X = pd.DataFrame() # to fill with counts
for idx, row in df.iterrows():
x1, y1 = row['CoordinateX'], row['CoordinateY']
addr_count = 0
indices = [] # to collect idx2 for dropping in df_X
df2 = df.copy()
for idx2, row2 in df2.iterrows():
x2, y2 = row2['Longitude'], row2['Lattitude']
distance = math.sqrt((x2-x1)**2 + (y2-y1)**2)
if distance <= R:
addr_count += 1
indices.append(idx2)
if addr_count > 0:
row['Count'] = addr_count
df_X = df_X.append(row, ignore_index=True)
df.drop(indices, inplace=True) # to exclude the rows in next iteration
df_X.shape
所以有 2 个循环 - 类似数据的外部和内部。
因为我的原始数据框有几千行,所以我想使用pd.apply() 优化计算。这是我用pd.apply 替换内部循环的代码:
def count_items(x1, y1, r, df):
def is_outside(x2, y2): return r < math.sqrt((x2-x1)**2 + (y2-y1)**2)
df_new = df[df.apply(lambda a: is_outside(a['CoordinateX'], a['CoordinateY']), axis=1)] # new set with distant addresses only
return df_new, len(df.index) - len(df_new.index)
def get_counted(r, df):
df_X = pd.DataFrame() # to fill with counts
for idx, row in df.iterrows():
x1, y1 = row['CoordinateX'], row['CoordinateX']
df2 = df.copy()
df3, addr_count = count_items(x1, y1, r, df2) # df3 contains now only distant addresses
if addr_count > 0:
row['Count'] = addr_count
df_X = df_X.append(row, ignore_index=True)
df = df3.copy()
return df_X
df_c = df.copy()
df_addrX = get_counted(R, df_c)
而且我不知道如何以同样的方式使用外部循环来增强部分。有人可以提供建议吗? BR,谢谢!
【问题讨论】:
标签: python pandas lambda apply