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

У меня есть следующий массив данных Pandas:

1    ["Apple", "Banana"]
2    ["Kiwi"]
3    None
4    ["Apple"]
5    ["Banana", "Kiwi"]

и следующий дикт:

{1: ["Apple", "Banana"],
2: ["Kiwi"]}

Теперь я хотел бы отобразить все записи в списках в моем фрейме данных, используя словарь. Результат должен быть следующим:

1    [1]
2    [2]
3    None
4    [1]
5    [1, 2]

Как это можно сделать наиболее эффективно?

+7
источник поделиться
3 ответа

Метод 1 я использую unnesting

d={z :  x for x , y in d.items() for z in y }
s=unnesting(s.to_frame().dropna(),[0])[0]\
   .map(d).groupby(level=0).apply(set).reindex(s.index)
Out[260]: 
0       {1}
1       {2}
2       NaN
3       {1}
4    {1, 2}
Name: 0, dtype: object

Способ 2 зациклите это

[set(d.get(y) for y in x) if  x is not None  else None for x in s ]
#s=[set(d.get(y) for y in x) if  x is not None  else None for x in s ]

Out[265]: [{1}, {2}, None, {1}, {1, 2}]

Ввод данных

s=pd.Series([["Apple", "Banana"],["Kiwi"],None,["Apple"],["Banana", "Kiwi"]])
d={1: ["Apple", "Banana"],
2: ["Kiwi"]}
+1
источник

Один из способов - сначала развернуть словарь и установить значения в качестве ключей, а соответствующие ключи - в качестве значений. И тогда вы можете использовать понимание списка и отобразить значения в каждом из списков в кадре данных.

Необходимо будет принять set перед возвратом результата сопоставления в каждой итерации, чтобы избежать повторных значений. Также обратите внимание, что or None делает то же самое, как if x is not None else None здесь, что вернет None в случае, если список пуст. Для более подробного объяснения этого вы можете проверить этот пост:

df = pd.DataFrame({'col1':[["Apple", "Banana"], ["Kiwi"], None, ["Apple"], ["Banana", "Kiwi"]]})
d = {1: ["Apple", "Banana"], 2: ["Kiwi"]}

d = {i:k for k, v in d.items() for i in v}
# {'Apple': 1, 'Banana': 1, 'Kiwi': 2}
out = [list(set(d[j] for j in i)) or None for i in df.col1.fillna('')]
# [[1], [2], None, [1], [1, 2]]
pd.DataFrame([out]).T

   0
0     [1]
1     [2]
2    None
3     [1]
4  [1, 2]
+1
источник

Опция 1

Перестройте словарь

m = {v: k for k, V in d.items() for v in V}

перестраивать

x = s.dropna()
v = [*map(m.get, np.concatenate(x.to_numpy()))]
i = x.index.repeat(x.str.len())
y = pd.Series(v, i)
y.groupby(level=0).unique().reindex(s.index)

0       [1]
1       [2]
2       NaN
3       [1]
4    [1, 2]
dtype: object

Если вы настаиваете на None а не NaN

y.groupby(level=0).unique().reindex(s.index).mask(pd.isna, None)

0       [1]
1       [2]
2      None
3       [1]
4    [1, 2]
dtype: object

Настроить

s = pd.Series([
    ['Apple', 'Banana'],
    ['Kiwi'],
    None,
    ['Apple'],
    ['Banana', 'Kiwi']
])

d = {1: ['Apple', 'Banana'], 2: ['Kiwi']}
+1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос