Поиск и назначение нескольких строк с помощью numpy.where или numpy.select в Python

#python #pandas #numpy

#питон #панды #тупица

Вопрос:

Я пытаюсь выполнить условное назначение строки — если ячейка содержит местоположения, назначьте географическое имя в ячейку рядом с ней. Я пробовал np.where , np.select и они, как правило, работают с одним назначением значения вместо нескольких назначений значений. Есть какие-нибудь предложения, как я могу сделать это через Numpy или есть более простой способ сделать это?

 Europe = ['London', 'Paris', 'Berlin'] North_America = ['New York', 'Toroto', 'Boston'] Asia = ['Hong Kong', 'Tokyo', 'Singapore']  data = {'location':["London, Paris", "Hong Kong", "London, New York", "Singapore, Toroto", "Boston"]} df = pd.DataFrame(data)   location 0 London, Paris 1 Hong Kong 2 London, New York 3 Singapore, Toroto 4 Boston  # np.where approach df['geo'] = np.where(( ( (df['location'].isin(Europe) ) ) | ( (df['location'].isin(North_America) ) ) ), 'Europe', 'North America')  # np.select approach conditions = [  df['location'].isin(Europe),  df['location'].isin(North_America) ] choices = ['Europe', 'North America'] df['geo'] = np.select(conditions, choices, default=0)  

Ожидаемый результат:

 location geo 0 London, Paris Europe, Europe 1 Hong Kong Asia 2 London, New York Europe, North America 3 Singapore, Toroto Asia, North America 4 Boston North America  

Комментарии:

1. Вам не нужно так много скобок, и вы можете указать значение df['location'] , чтобы сделать код немного более читаемым/чистым, но это незначительное изменение.

Ответ №1:

Создайте карту каждой страны -gt; область, затем используйте gt; explode и map для применения карты и, наконец, используйте groupby и apply для восстановления списка:

 geo = {'Europe': Europe, 'North_America': North_America, 'Asia': Asia} mapping = {country: area for area, countries in geo.items() for country in countries}  df['geo'] = df['location'].str.split(', ').explode().map(mapping)   .groupby(level=0).apply(', '.join)  

Выход:

 gt;gt;gt; df  location geo 0 London, Paris Europe, Europe 1 Hong Kong Asia 2 London, New York Europe, North_America 3 Singapore, Toroto Asia, North_America 4 Boston North_America  

Ответ №2:

Используя библиотеку NumPy вместе с for циклами python, мы можем получить результаты. Сначала мы объединяем списки городов страны вместе, а затем создаем другой список с названием континенты, длина которого совпадает с созданным списком городов:

 import numpy as np import pandas as pd  continents = ["Europe"] * len(Europe)   ["North_America"] * len(North_America)   ["Asia"] * len(Asia) countries = Europe   North_America   Asia locations = data['location']  

Затем для каждого города, даже для каждого из комбинаций, мы находим его индекс в созданном списке стран. Затем мы создаем список для количества запятых в каждой из этих комбинаций для использования для создания желаемого результата с запятыми:

 corsp = [] comma_nums = [] for i in locations:  for j, k in enumerate(i.split(', ')):  corsp.append(np.where(np.array(countries) == k)[0][0])  comma_nums.append(j)  

список континентов будет переупорядочен и изменен созданным индексным списком. Затем его аргументы объединяются в формате списка в качестве стиля комбинации, который находится в местоположениях, а затем списки преобразуются в строки по мере их необходимости для вывода:

 reordered_continents = [continents[i] for i in corsp]  mod_continents = [] iter = 0 f = 1 for i in comma_nums:  mod_continents.append(reordered_continents[iter:i   f])  iter = i   f  f = iter   1  for i, j in enumerate(mod_continents):  if len(j) gt; 1:  for k in j:  mod_continents[i] = ', '.join(j)  else:  mod_continents[i] = ''.join(j)  df['geo'] = mod_continents