#python-3.x #pandas #dataframe #python-3.6
#python-3.x #pandas #фрейм данных #python-3.6
Вопрос:
У меня есть столбец фрейма данных pandas, который содержит оба list
str
значения и . Я только пытаюсь преобразовать str
значения в правильный list
формат, чтобы он соответствовал другим list
значениям формы. Я нашел исправление, но я хочу посмотреть, есть ли лучший способ сделать это? Ниже приведены мои вопросы:
- Если есть функциональность / возможность сборки pandas для использования вместо записи long
regex
,replace
, ..etc? - Как преобразовать
[nan]
в[]
без регулярных выражений?
Вот моя попытка:
Файл данных:
StudentName,CourseID
Alan,"['abc-12-0878', 'abc-12-45', 'abc-12-232342']"
Tim,"['abc-12-0878', 'abc-12-45']"
David,abc-12-1147
Martha,
Matt,"['abc-12-0878', 'abc-12-45']"
Abby,abc-12-1148
Мой код пытается:
import pandas as pd
df = pd.read_csv('sample_students.csv')
df
df['result'] = df['CourseID'].astype(str).apply(lambda x: x.strip('[]').replace("'","").split(','))
# Regex route.
# Pandas`s build in function available?
# gives `[nan]` instead of `[]`
# `to_list` and `tolist` didn't work.
Результат, который я ищу:
print(df[['CourseID','result']])
CourseID result
['abc-12-0878', 'abc-12-45', 'abc-12-232342'] ['abc-12-0878', 'abc-12-45', 'abc-12-232342']
['abc-12-0878', 'abc-12-45'] ['abc-12-0878', 'abc-12-45']
abc-12-1147 ['abc-12-1147']
NaN []
['abc-12-0878', 'abc-12-45'] ['abc-12-0878', 'abc-12-45']
abc-12-1148 [abc-12-1148]
Ответ №1:
Вы можете применить ast.literal_eval() для синтаксического анализа буквального представления списка.
import ast
def f(s):
if pd.isna(s): # case 1: nan
return []
elif s[0] == "[": # case 2: string of list
return ast.literal_eval(s)
else: # case 3: string
return [s]
df["result"] = df["CourseID"].apply(f)
Или в однострочном:
df["result"] = df["CourseID"].apply(lambda s: [] if pd.isna(s) else ast.literal_eval(s) if s[0] == "[" else [s])
Результат:
print(df[["CourseID","result"]])
CourseID result
0 ['abc-12-0878', 'abc-12-45', 'abc-12-232342'] [abc-12-0878, abc-12-45, abc-12-232342]
1 ['abc-12-0878', 'abc-12-45'] [abc-12-0878, abc-12-45]
2 abc-12-1147 [abc-12-1147]
3 NaN []
4 ['abc-12-0878', 'abc-12-45'] [abc-12-0878, abc-12-45]
5 abc-12-1148 [abc-12-1148]
Ответ №2:
Если вы предпочитаете не импортировать другую библиотеку, вы можете сделать это следующим образом:
def update_data(val):
if pd.isna(val):
return []
if val[0] == '[':
return val
return [val]
df['Result'] = df.apply(lambda row: update_data(row['CourseID']), axis= 1)
Ответ №3:
Вы можете проверить только тип значения
df['result'] = df['CourseID'].apply(lambda x: x.strip('[]').replace("'","").split(',') if type(x) == str else [])
>>> print(df[['CourseID','result']])
CourseID result
0 ['abc-12-0878', 'abc-12-45', 'abc-12-232342'] [abc-12-0878, abc-12-45, abc-12-232342]
1 ['abc-12-0878', 'abc-12-45'] [abc-12-0878, abc-12-45]
2 abc-12-1147 [abc-12-1147]
3 NaN []
4 ['abc-12-0878', 'abc-12-45'] [abc-12-0878, abc-12-45]
5 abc-12-1148 [abc-12-1148]
Комментарии:
1. Я не проверял, что происходит, когда идентификатор курса равен и является целым или плавающим