#python #pandas #list #extract #expand
#python #pandas #Список #извлечь #Развернуть
Вопрос:
У меня есть этот df (с образцом желаемого результата)
dfn = pd.DataFrame({"country_code": ["USA, UK, FRA", "RUS, ZHC, JAP", "IN, BRA, ES"],
"all_but_american_desired": [["United Kingdom", "France"], ["Russia", "China", "Japan"], ["India", "Spain"]]})
где я «перевожу» (пока) строки в новые значения и сохраняю в виде списка элементов
masked = {"USA":"United States", "UK":"United Kingdom", "FRA":"France",
"RUS":"Russia", "ZHC":"China", "JAP":"Japan",
"IN":"India", "BRA":"Brazil", "ES":"Spain"}
dfn["country_name"] = dfn["country_code"].apply(lambda x: [", ".join({masked[i] for i in x.split(", ")})])
Затем я хотел бы извлечь некоторые из переведенных серий country_name, идущих по внешнему списку, american
и поместить их в отдельную серию ( all_but_american
)
american = ["United States", "Brazil"]
Результат должен быть таким же, как у all_but_american_desired
серии. Что я пробовал до сих пор:
dfn["all_but_american1"] = dfn["country_name"].apply(lambda x: [i for i in x if i not in american])
Ранее я использовал тот же подход attempt1, и он сработал, но на этот раз ничего не работает, и я не могу найти причину этого (на этот раз я также пробовал другие подходы, но, поскольку я с ними не знаком, я воздержусь от публикации)… Может кто-нибудь проверить это, пожалуйста? Если возможно, с объяснением того, что я тоже делаю неправильно.
Ответ №1:
Для country_name
создания списков вместо одного списка элементов с объединенными значениями:
dfn["country_name"] = dfn["country_code"].apply(lambda x: [masked[i] for i in x.split(", ")])
И тогда ваше второе решение работает хорошо:
american = ["United States", "Brazil"]
dfn["all_but_american1"] = dfn["country_name"].apply(lambda x: [i for i in x if i not in american])
print (dfn)
country_code all_but_american_desired
0 USA, UK, FRA [United Kingdom, France]
1 RUS, ZHC, JAP [Russia, China, Japan]
2 IN, BRA, ES [India, Spain]
country_name all_but_american1
0 [United States, United Kingdom, France] [United Kingdom, France]
1 [Russia, China, Japan] [Russia, China, Japan]
2 [India, Brazil, Spain] [India, Spain]
Комментарии:
1. Герой! Правильный ответ, как всегда. Спасибо @jezrael! Мне любопытно, если бы вы закончили, можно ли было бы «извлечь» и «взорвать» серию country_name при ее создании в отдельную, содержащую только элементы из американского списка? Вместо того, чтобы создавать его «с нуля»? Я не уверен, насколько это было бы питоническим или эффективным (вероятно, не очень), но хотел бы посмотреть, как это будет выглядеть (лямбда или обычная функция)
2. Нет, я говорю, вместо того, чтобы создавать «all_but_american», используя эту лямбду, создайте его в той же строке, где мы создаем «country_name», заставляя его «расширяться», если результирующий список из замаскированных элементов включает элементы из «американского» списка. Если это слишком сложно объяснить, это определенно будет не очень pythonic, но звучит как хороший эксперимент 🙂
3. Закрыть — результат этого совпадает с текущим
all_but_american1
, просто минуя созданиеcountry_name
серии. Я хочу сказать, что вместо полной фильтрацииamerican
элементов «извлеките» / «разнесите» эти элементы для хранения в другой серии. Не по теме: также хотелось бы знать, есть ли способ добавить последний элемент списка-серии (напримерcountry_name
) в другой список-серии (напримерall_but_american1
), если они соответствуют определенным критериям. Так, например, добавьтеcountry_name[-1]
all_but_american1
, если этот элемент == «Япония»4. @cjcrm — Я думаю, что лучше всего создать новый вопрос — для первого возможно использование
dfn["all_but_american1"] = dfn["country_name"].apply(lambda x: [i for i in x if i not in american])
иdfn["all_american1"] = dfn["country_name"].apply(lambda x: [i for i in x if i in american])
/ или пользовательской функции с добавлением в 2 списка5. Да, имеет смысл разделить вопросы. Еще раз, большое вам спасибо @jezrael, очень признателен!