Преобразование столбца данных в несколько строк, повторение значений других столбцов - PullRequest
0 голосов
/ 19 сентября 2018

Это мой CSV:

languages,    origin,     other_test1,       other_test2
"[{'name': 'French', 'vowel_count': 3}, {'name': 'Dutch', 'vowel_count': 4}, {'name': 'English', 'vowel_count': 5}]",Germanic,ABC,DEF

Я хочу преобразовать колонку языков CSV в следующий вывод:

Language_name ,Language_vowel_count, origin,    other.test1, other.test2
French,        3,                    Germanic,  ABC,         DEF
Dutch,         4,                    Germanic,  ABC,         DEF
English,       5,                    Germanic,  ABC,         DEF

Код, который я пробовал:

 from itertools import chain

 a = df['languages'].str.findall("'(.*?)'").astype(np.object)
 lens = a.str.len()

  df = pd.DataFrame({
'origin' : df['origin'].repeat(lens),
'other_test1' : df['other_test1'].repeat(lens),
'other_test2' : df['other_test2'].repeat(lens),
'name' : list(chain.from_iterable(a.tolist())),
'vowel_count' : list(chain.from_iterable(a.tolist())),
})

df

Но это не дает мне ожидаемый результат.

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018
import re
import pandas as pd
import json
csv = """"[{'name': 'French', 'vowel_count': 3}, {'name': 'Dutch', 'vowel_count': 4}, {'name': 'English', 'vowel_count': 5}]",Germanic,ABC,DEF"""
csv = re.split('(?![^)(]*\([^)(]*?\)\)),(?![^\[]*\])',csv)
df = pd.DataFrame(json.loads(csv[0].replace("'",'"')[1:-1]))
df['Origin']=csv[1]
df['other.test1']=csv[2]
df['other.test2']=csv[3]
df

enter image description here

0 голосов
/ 19 сентября 2018

Вы можете использовать понимание вложенного списка для распаковки данных вместе с ast.literal_eval для преобразования строки JSON в словарь Python.

import ast

>>> pd.DataFrame(
    [[languages.get('name'), languages.get('vowel_count'), row['origin'], row['other_test1'], row['other_test2']]
     for idx, row in df.iterrows() 
     for languages in ast.literal_eval(row['languages'])],
    columns=['Language_name', 'Language_vowel_count', 'origin', 'other.test1', 'other.test2'])
  Language_name  Language_vowel_count    origin other.test1 other.test2
0        French                     3  Germanic         ABC         DEF
1         Dutch                     4  Germanic         ABC         DEF
2       English                     5  Germanic         ABC         DEF

Альтернативный метод без использования iterrows объединяетраспакованные языки с базовыми данными:

languages = df['languages'].apply(lambda x: ast.literal_eval(x))

df_lang = pd.DataFrame(
    [(lang.get('name'), lang.get('vowel_count')) 
     for language in languages 
     for lang in language])

df_new = pd.concat([
    df_lang, 
    df.iloc[:, 1:].reindex(df.index.repeat([len(x) for x in languages])).reset_index(drop=True)], axis=1)

df_new.columns = ['Language_name', 'Language_vowel_count', 'origin', 'other.test1', 'other.test2']
...