Добавить новый столбец из списка словаря - PullRequest
3 голосов
/ 06 августа 2020

У меня есть DataFrame, в котором есть столбец, состоящий из dict, я хочу извлечь все ключи и значения и сделать их двумя новыми столбцами.

   a                 b
0  1  {'a': 1, 'b': 2}
1  2  {'k': 4, 'v': 6}
2  3          {'z': 3}

вывод будет

   a  k  v
0  1  a  1
1  1  b  2
2  2  k  4
3  2  v  6
4  3  z  3

Ответы [ 4 ]

1 голос
/ 06 августа 2020

Вы можете попробовать groupby, apply, rename_axis и reset_index:

>>> df.groupby('a').apply(lambda x:pd.Series(x.b[0], name='v'))
                   .rename_axis(['a','k']).reset_index()

   a  k  v
0  1  a  1
1  1  b  2
2  2  k  4
3  2  v  6
4  3  z  3
1 голос
/ 06 августа 2020

Используйте понимание списка со сглаженными значениями для списка кортежей и переходите к DataFrame конструктору:

L = [(x, k, v) for x, y in df[['a','b']].values for k, v in y.items()]
df = pd.DataFrame(L, columns=['a','k','v'])
print (df)
   a  k  v
0  1  a  1
1  1  b  2
2  2  k  4
3  2  v  6
4  3  z  3

EDIT: для общего решения, работающего с уникальным индексом, возможно изменение решения с помощью DataFrame.pop для извлечения b столбца, добавления нового столбца idx по значениям индекса, преобразования в индекс и последнего использования DataFrame.join:

L = [(x, k, v) for x, y in df.pop('b').items() for k, v in y.items()]
df1 = pd.DataFrame(L, columns=['idx','k','v']).set_index('idx').rename_axis(None)
df = df.join(df1).reset_index(drop=True)
print (df)
   a  k  v
0  1  a  1
1  1  b  2
2  2  k  4
3  2  v  6
4  3  z  3
0 голосов
/ 06 августа 2020

Вы можете развернуть словарь, explode столбец и применить функцию pd.Series для получения результата:

df = pd.DataFrame({"a": [1, 2, 3], "b": [{"a": 1, "b": 2}, {"k": 4, "v": 6}, {"z": 3}]})

divider = df.columns.get_loc("b")

# expand dictionary within the `b` column
df["b"] = [tuple(entry.items()) for entry in df.b]

# merge dataframe before `b`, the exploded `b` column, and the dataframe after `b`
merger = (
    df.iloc[:, :-divider],
    df.b.explode().apply(pd.Series).set_axis(["k", "v"], axis=1),
    df.iloc[:, : -(divider + 1)],
)
pd.concat(merger, axis=1)

    a   k   v
0   1   a   1
0   1   b   2
1   2   k   4
1   2   v   6
2   3   z   3
0 голосов
/ 06 августа 2020

Сначала я создал исходный фрейм данных:

df = pd.DataFrame({'a': [1, 2, 3],
                   'b': [{'a': 1, 'b': 2},
                         {'k': 4, 'v': 6},
                         {'z': 3}]
                  })

Затем перебрал строки фрейма данных и перебрал словарь в столбце B:

ts = list()

for row in df.itertuples():
    for key, value in row.b.items():
        t = (row.Index, row.a, key, value)
        ts.append(t)

print(pd.DataFrame(data=ts, columns=['Index', 'a', 'k', 'v']).set_index('Index'))

      a  k  v
Index         
0      1  a  1
0      1  b  2
1      2  k  4
1      2  v  6
2      3  z  3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...