Изменение формы беспорядочного набора данных с использованием Pandas - PullRequest
0 голосов
/ 04 августа 2020

Я получил этот беспорядочный набор данных из csv-файла, который содержит несколько записей в одной ячейке. Вот как это выглядит:

file = ('messy.csv')
df = pd.read_csv(file)

df.head()


Folders            Files
                                          
aa; bb;            aa.src aa.xml ; bb.src bb.war ;
cc;                cc.pom cc.py cc.js ;
dd; ee; ff;        dd.ts dd.js ; ee.py ; ff.xml ff.js ;

В столбце «Папки» значения разделяются точкой с запятой «;». В столбце «Файлы» значения разделяются пробелом и точкой с запятой «;». Файлы, принадлежащие одной папке, разделяются только пробелом. Мне нужна помощь, чтобы преобразовать это в более управляемый фреймворк или в JSON -dict / list. Я не нашел много примеров, в которых есть несколько значений в одной и той же ячейке, от которых я мог бы получить помощь.

Конечно, «управляемый» формат неоднозначен, но все может быть лучше этого ... 1006 *

Может быть, что-то вроде этого:

Folders            Files 1   Files 2   Files 3
                                          
aa                 aa.src    aa.xml    NaN
bb                 bb.src    bb.war    NaN
cc                 cc.pom    cc.py     cc.js
dd                 dd.ts     dd.js     NaN
ee                 ee.py     NaN       NaN
ff                 ff.xml    ff.js     NaN

Или, если есть лучшие идеи, я открыт для предложений. После того, как я изменил его форму, он будет преобразован в формат JSON.

1 Ответ

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

Превращение его в json / dict

Хорошо, вероятно, не самое эффективное решение, но оно работает:

import pandas as pd

# Recreating the dataframe
df = pd.DataFrame({'Folders':["aa; bb;", "cc", "dd; ee; ff;"], 'Files':['aa.src aa.xml ; bb.src bb.war ;', 'cc.pom cc.py cc.js ;', 'dd.ts dd.js ; ee.py ; ff.xml ff.js ;']})

#Split df according to ; and removing leading ;
df = df.apply(lambda x: x.str.rstrip(';').str.split(';'))
print(df)

Итак, теперь ваш фрейм данных выглядит так :

          Folders                                    Files
0       [aa,  bb]        [aa.src aa.xml ,  bb.src bb.war ]
1            [cc]                    [cc.pom cc.py cc.js ]
2  [dd,  ee,  ff]  [dd.ts dd.js ,  ee.py ,  ff.xml ff.js ]

Затем я l oop через фрейм данных, чтобы построить dict:

# Creating the dict by looping through the dataframe and number of elements of folders
df_dict=dict()
for index, row in df.iterrows():
  for i, key in enumerate(row['Folders']):
    df_dict[key.strip()] = row['Files'][i].strip().split(' ')

print(df_dict)
    

И вот результат:

{'aa': ['aa.src', 'aa.xml'], 'bb': ['bb.src', 'bb.war'], 'cc'
: ['cc.pom', 'cc.py', 'cc.js'], 'dd': ['dd.ts', 'dd.js'], 'ee
': ['ee.py'], 'ff': ['ff.xml', 'ff.js']}

Если вы может встретить дважды один и тот же ключ, я предлагаю использовать эту версию кода, которая проверяет, существует ли уже ключ:

import pandas as pd

# Recreating the dataframe
df = pd.DataFrame({'Folders':["aa; bb;", "cc", "dd; ee; ff;", 'aa'], 'Files':['aa.src aa.xml ; bb.src bb.war ;', 'cc.pom cc.py cc.js ;', 'dd.ts dd.js ; ee.py ; ff.xml ff.js ;', 'aa.tst']})

#Split df according to ; and removing leading ;
df = df.apply(lambda x: x.str.rstrip(';').str.split(';'))
print(df)

df_dict=dict()
for index, row in df.iterrows():
  for i, key in enumerate(row['Folders']):
    if key.strip() in df_dict:
      df_dict[key.strip()] += row['Files'][i].strip().split(' ')
    else: df_dict[key.strip()] = row['Files'][i].strip().split(' ')

print(df_dict)
...