Как мне избежать 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()
. Это мой код, который заменяет внутренний l oop на 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)
И я понятия не имею, как таким же образом улучшить деталь с внешним l oop. Кто-нибудь может предоставить предложение, пожалуйста? BR, спасибо!