#python #pandas
#python #pandas
Вопрос:
У меня есть данные опроса, в которых один столбец выглядит следующим образом:
Evaluations_Col
E: 3, D: 3, C: 3, S: 3, E: 3, X, K: 3
E: 1, D: 1, C: 1, S: 1, E: 1, X, K: 1
E: 2, D: 2, C: 2, S: 2, E: 2, X, K: 2
E: 5, D: 5, C: 5, S: 5, E: 5, X, K: 5
E: 3, D: 1, C: 1, S: 1, E: 1, X, K: 1
ПРИМЕЧАНИЕ: мне нужно игнорировать значения X в столбцах.
Я хочу извлечь каждую оценку и разделить их как столбцы отдельно для каждого типа оценки. и в конце ожидаемые столбцы будут похожи:
E_col D_col C_Col ...
3 3 3
1 1 1
2 2 2
5 5 5
3 1 1
Возможно, я могу разделить их на запятую и получить список, подобный этому, [E: 3, D: 3, C: 3, S: 3, E: 3, K: 3]
Что, как создать отдельный столбец для каждого и правильно распределить соответствующие значения?
Я могу нормально достичь этого, но значения X вызывают проблему со словарем bc… Как я могу это исключить?
df1 = pd.DataFrame([dict([y.split(':') for y in x.split(',')]) for x in test_col])
df1.head()
ошибка
ValueError: dictionary update sequence element #9 has length 1; 2 is required
Ответ №1:
Использование понимания списка и фильтрации строк, содержащих только разделитель ‘:’:
Давайте разберем понимание списка на части:
- Цикл по строкам :
for x in test_col
- Разделение только строк (обозначаемых
x
) на столбцы путем разделения на ‘,’ :for y in x.split(',')
- Разделение столбца на пару ключ-значение только в том случае, если существует разделитель ‘:’ :
y.split(':') for y in x.split(',') ***only*** if ':' in y
(это решает описанную проблему)
Код:
import pandas as pd
import numpy as np
test_col = []
with open('data.csv', 'r') as f:
test_col = [l.strip() for l in f.readlines()]
df = pd.DataFrame([dict([y.split(':') for y in x.split(',') if ':' in y]) for x in test_col])
print(df.head())
Вывод:
E D C S E K
0 3 3 3 3 3 3
1 1 1 1 1 1 1
2 2 2 2 2 2 2
3 5 5 5 5 5 5
4 3 1 1 1 1 1
Ответ №2:
Один из способов — использовать str.extractall
:
s = df["Value"].str.extractall(r"([A-Z]):s(d)").reset_index().groupby("level_0")
print (pd.DataFrame(s[1].agg(list).tolist(), columns=s[0].get_group(0).tolist()))
E D C S E K
0 3 3 3 3 3 3
1 1 1 1 1 1 1
2 2 2 2 2 2 2
3 5 5 5 5 5 5
4 3 1 1 1 1 1
Комментарии:
1. Я получаю эту ошибку ->
Length of passed values is 0, index implies 2.
Ответ №3:
используя str.split
и stack
df1 = (
df["Evaluations_Col"]
.str.split(",", expand=True)
.stack()
.str.split(":", expand=True)
.set_index(0, append=True)
.dropna()
.unstack([1, 2])
.droplevel(1,1)
)
1
0 E D C S E K
0 3 3 3 3 3 3
1 1 1 1 1 1 1
2 2 2 2 2 2 2
3 5 5 5 5 5 5
4 3 1 1 1 1 1