#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