Сводный столбец Pandas списков

#python #pandas #list #dataframe #pivot-table

#python #pandas #Список #фрейм данных #сводная таблица

Вопрос:

У меня есть фрейм данных pandas, в котором есть столбец, значениями которого являются списки, а другой столбец — дата. Я хотел бы создать фрейм данных, который подсчитывает элементы списков по дате.

Фрейм данных выглядит следующим образом:

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

 pd.DataFrame(
    data={
        "col1": ["['a','b']", "['b','c']", "['a','c']", "", "['b']"],
        "col2": ["2020-01-01", "2020-01-02", "2020-01-03", "2020-01-04", "2020-01-05"],
    },
    index=[0, 1, 2, 3, 4],
)
  

Я бы хотел, чтобы фрейм данных выглядел следующим образом:

Изображение желаемого фрейма данных

 pd.DataFrame(
    data={"a": [1, 0, 1, 0, 0], "b": [1, 1, 0, 0, 1], "c": [0, 1, 1, 0, 0]},
    index=["2020-01-01", "2020-01-02", "2020-01-03", "2020-01-04", "2020-01-05"],
)
  

Есть мысли о том, как выполнить такое преобразование?

Ответ №1:

Вы можете использовать pd.crosstab здесь.

 df['col1'] = df['col1'].str.findall('w ')
df_ = df.explode('col1')
pd.crosstab(df_['col2'], df_['col1']).reindex(df_['col2'].unique()).fillna(0)

col1          a    b    c
col2                     
2020-01-01  1.0  1.0  0.0
2020-01-02  0.0  1.0  1.0
2020-01-03  1.0  0.0  1.0
2020-01-04  0.0  0.0  0.0
2020-01-05  0.0  1.0  0.0
  

Ответ №2:

Вы можете использовать extractall для извлечения значений внутри '' , а затем подсчитывать значения с помощью groupby :

 out= (df.col1.str.extractall("'([^']*)'")
   .groupby(level=0)[0].value_counts()
   .unstack(level=1,fill_value=0)
   .reindex(df.index, fill_value=0)
)

out.index= df['col2']
print(out)
  

Вывод:

 0           a  b  c
col2               
2020-01-01  1  1  0
2020-01-02  0  1  1
2020-01-03  1  0  1
2020-01-04  0  0  0
2020-01-05  0  1  0
  

Комментарии:

1. Это сильный ответ, спасибо, Куанг. Однако я должен был быть более ясным — в моем наборе данных даты иногда могут повторяться, и я хотел бы суммировать общую сумму переменной для всех вхождений этой даты

2. @enixon4 Вместо out.index=df['col2'] do out.groupby(df['col2']).sum() 🙂

Ответ №3:

Вы могли бы сделать это таким образом:

 
df = pd.DataFrame(
    data={
        "col1": [['a','b'], ['b','c'], ['a','c'], ['c'], ['b']],
        "col2": ["2020-01-01", "2020-01-02", "2020-01-03", "2020-01-04", "2020-01-05"],
    }
)
df2 = df.explode('col1').reset_index(drop=True)
df2["value"]=1
pd.pivot_table(df2, values="value", index=["col2"], columns=["col1"], aggfunc=lambda x: 1, fill_value=0) 
  

Комментарии:

1. Я думаю, что это могло бы быть лучше, если бы вы создали перекрестную таблицу вместо сводной таблицы, IMO pd.crosstab(index = df2.col2, columns = df2.col1) . Это также позволит вам отказаться df2['value'] = 1

2. ДА. Я видел решение toue. Приятно !