Извлечь элемент из списка pandas-серии и сохранить как отдельную серию

#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, очень признателен!