для цикла, использующего iterrows в пандах

У меня есть 2 кадра данных следующим образом:

data1 выглядит так:

id address 1 11123451 2 78947591 

data2 выглядит следующим образом:

 lowerbound_address upperbound_address place 78392888 89000000 X 10000000 20000000 Y 

Я хочу создать еще один столбец в data1, называемый «местом», который содержит место, откуда находится идентификатор. Например, в приведенном выше случае для id 1 я хочу, чтобы столбец места содержал Y и для id 2, я хочу, чтобы столбец места содержал X. Будет много идентификаторов, поступающих из одного и того же места. И некоторые идентификаторы не имеют соответствия.

Я пытаюсь сделать это, используя следующий фрагмент кода.

 places = [] for index, row in data1.iterrows(): for idx, r in data2.iterrows(): if r['lowerbound_address'] <= row['address'] <= r['upperbound_address']: places.append(r['place']) 

Адреса здесь являются значениями float.

Это навсегда запустит этот кусок кода. Это заставляет меня задаться вопросом, правильный ли мой код или есть ли более быстрый способ его выполнения.

Любая помощь будет высоко ценится. Спасибо!

One Solution collect form web for “для цикла, использующего iterrows в пандах”

Вы можете использовать первое cross соединение с merge а затем фильтровать значения с помощью boolean indexing . Последний удалить ненужные столбцы:

 data1['tmp'] = 1 data2['tmp'] = 1 df = pd.merge(data1, data2, on='tmp', how='outer') df = df[(df.lowerbound_address <= df.address) & (df.upperbound_address >= df.address)] df = df.drop(['lowerbound_address','upperbound_address', 'tmp'], axis=1) print (df) id address place 1 1 11123451 Y 2 2 78947591 X 

Другое решение с itertuples , последнее создание DataFrame.from_records :

 places = [] for row1 in data1.itertuples(): for row2 in data2.itertuples(): #print (row1.address) if (row2.lowerbound_address <= row1.address <= row2.upperbound_address): places.append((row1.id, row1.address, row2.place)) print (places) [(1, 11123451, 'Y'), (2, 78947591, 'X')] df = pd.DataFrame.from_records(places) df.columns=['id','address','place'] print (df) id address place 0 1 11123451 Y 1 2 78947591 X 

Другое решение:

 def f(x): for row2 in data2.itertuples(): if (row2.lowerbound_address <= x <= row2.upperbound_address): return pd.Series([x, row2.place], index=['address','place']) df = data1.set_index('id')['address'].apply(f).reset_index() print (df) id address place 0 1 11123451 Y 1 2 78947591 X 

РЕДАКТИРОВАТЬ:

Сроки :

N = 1000 :

Если значения saome не находятся в зоне действия, в решениях b и c нет. Проверьте последнюю строку df1 .

 In [73]: %timeit (data1.set_index('id')['address'].apply(f).reset_index()) 1 loop, best of 3: 2.06 s per loop In [74]: %timeit (a(df1a, df2a)) 1 loop, best of 3: 82.2 ms per loop In [75]: %timeit (b(df1b, df2b)) 1 loop, best of 3: 3.17 s per loop In [76]: %timeit (c(df1c, df2c)) 100 loops, best of 3: 2.71 ms per loop 

Код для таймингов :

 np.random.seed(123) N = 1000 data1 = pd.DataFrame({'id':np.arange(1,N+1), 'address': np.random.randint(N*10, size=N)}, columns=['id','address']) #add last row with value out of range data1.loc[data1.index[-1]+1, ['id','address']] = [data1.index[-1]+1, -1] data1 = data1.astype(int) print (data1.tail()) data2 = pd.DataFrame({'lowerbound_address':np.arange(1, N*10,10), 'upperbound_address':np.arange(10,N*10+10, 10), 'place': np.random.randint(40, size=N)}) print (data2.tail()) df1a, df1b, df1c = data1.copy(),data1.copy(),data1.copy() df2a, df2b ,df2c = data2.copy(),data2.copy(),data2.copy() 

 def a(data1, data2): data1['tmp'] = 1 data2['tmp'] = 1 df = pd.merge(data1, data2, on='tmp', how='outer') df = df[(df.lowerbound_address <= df.address) & (df.upperbound_address >= df.address)] df = df.drop(['lowerbound_address','upperbound_address', 'tmp'], axis=1) return (df) 

 def b(data1, data2): places = [] for row1 in data1.itertuples(): for row2 in data2.itertuples(): #print (row1.address) if (row2.lowerbound_address <= row1.address <= row2.upperbound_address): places.append((row1.id, row1.address, row2.place)) df = pd.DataFrame.from_records(places) df.columns=['id','address','place'] return (df) 

 def f(x): #use for ... else for add NaN to values out of range #http://stackoverflow.com/q/9979970/2901002 for row2 in data2.itertuples(): if (row2.lowerbound_address <= x <= row2.upperbound_address): return pd.Series([x, row2.place], index=['address','place']) else: return pd.Series([x, np.nan], index=['address','place']) 

 def c(data1,data2): data1 = data1.sort_values('address') data2 = data2.sort_values('lowerbound_address') df = pd.merge_asof(data1, data2, left_on='address', right_on='lowerbound_address') df = df.drop(['lowerbound_address','upperbound_address'], axis=1) return df.sort_values('id') print (data1.set_index('id')['address'].apply(f).reset_index()) print (a(df1a, df2a)) print (b(df1b, df2b)) print (c(df1c, df2c)) 

Только решение c с merge_asof работает с большим DataFrame :

N=1M :

 In [84]: %timeit (c(df1c, df2c)) 1 loop, best of 3: 525 ms per loop 

Подробнее о слиянии asof в документах .

  • Python устанавливает панды
  • Как заполнить отсутствующую запись данных Pandas в виде pythonic?
  • Ошибка данных запаса python pandas yahoo
  • Pandas Correlation Groupby
  • Как показать кадр данных pandas в виде таблицы с флеш-накопителем?
  • Добавление столбца фрейма данных с len () значений другого столбца
  • Сторнирование string.contains В python, pandas
  • сравнивая массив dtyped со скаляром типа в Pandas DataFrame
  • Создание меток-точек из Spark DataFrame в Python
  • Pandas: объединение фреймов данных в индексе даты и времени
  • Pandas msgpack против рассола
  •  
    Interesting Posts for Van-Lav

    как внести вклад в обученную и проверенную сеть PyBrain и как получить результат

    Свойства класса только для чтения python

    python pandas TimeStamps для локальной временной строки с летним временем

    Как подсчитать количество предложений, слов и символов в файле?

    wxpython auinotebook закрыть вкладку

    Точка безубыточности оптимизации: многократно повторяйте набор или конвертируйте в список в первую очередь?

    Как исключить один файл из пакета с setuptools и setup.py

    Смещение радиальной оси полярного участка Matplotlib

    Я не могу импортировать Flask-WTF TextField и BooleanField

    Удалите дубликаты в списке, сохраняя при этом его порядок (Python)

    Почему строка Unicode не отображается на консоли PyCharm?

    В чем разница между scipy.integrate.odeint и scipy.integrate.ode?

    Отображение изображения, сохраненного в виде двоичного блока в шаблоне

    Как добавить данные пакета рекурсивно в Python setup.py?

    ошибка времени выполнения в простом коде Python (NZEC)

    Python - лучший язык программирования в мире.