Разделить фрейм данных по пустой строке и изменить заголовки

У меня есть лист CSV с несколькими таблицами на листе, как это:

Name     Header-1     Header-8     Header 3
Random Note
Jack     X                         X
Jane                    X
NAN      NAN          NAN          NAN
Name     Header 3     Header 2     Header 7
Random note
Jeremy   X            X
Joey                               X

Могу ли я разбить таблицы на пустые строки, а затем преобразовать их в один фрейм данных, чтобы получить такой результат:

Name     Header-1     Header-2     Header-3     .....
Jack     X
Jane                    X
Jeremy                              X
Joey         X          X            X

Я хотел бы использовать пустые строки в качестве нового индекса и читать каждую таблицу как новый df. Заголовки каждой таблицы одинаковы, они просто не все в правильном порядке. В конце концов - я бы хотел соединить их обратно в один чистый DF.

1 ответ

Предположим, вы установили CSV следующим образом:

Name,Header-1,Header-2,Header-3
Random,Note, , 
Jack,X,X,   
Jane,X, , 
,,,
Name,Header-3,Header-2,Header-1
Random,note, , 
Jeremy,X,X, 
Joey, , ,X

Вы можете работать с этим файлом с помощью следующего кода, который не требует пояснений:

import pandas as pd
# Read csv file
df = pd.read_csv("D:/tmp/data.csv", sep=',')

#Find columns which are null, create partitions and group by them
isnull = (df["Name"].isnull())
partitions = (isnull != isnull.shift()).cumsum()
gb = df[~isnull].groupby(partitions)
keys = gb.groups.keys()

# Extract all the dataframes
dfs = [gb.get_group(g) for g in keys]

datas = []
# Set the header as first row for all dataframes that are not the first one
for i,data in enumerate(dfs):
    if i!=0:    # First dataframe has already set the correct header
        data.columns = data.ix[data.index[0]]
        data = data.drop(data.index[0])
    datas.append(data)

# Concatenate the dataframes and reset the index
df_concat = pd.concat(datas)
df_out = df_concat.reset_index(drop=True)

# Change the order of the columns to get "Name" as first column
cols = df_out.columns.tolist()
cols = cols[-1:] + cols[:-1]
df_out = df_out[cols]

Итак, ваш вклад:

>>> df
     Name  Header-1  Header-2  Header-3
0  Random      Note                    
1    Jack         X         X           
2    Jane         X                    
3     NaN       NaN       NaN       NaN
4    Name  Header-3  Header-2  Header-1
5  Random      note                    
6  Jeremy         X         X          
7    Joey                             X

Обратите внимание, что в этом примере заголовок находится в другом порядке во втором кадре данных для извлечения.

И ваш вывод будет:

>>> df_out
     Name Header-1 Header-2 Header-3
0  Random     Note                  
1    Jack        X        X         
2    Jane        X                  
3  Random                       note
4  Jeremy                 X        X
5    Joey        X                  
Другие вопросы по тегам