Панды: Как читать DataFrame из файла Excel, где несколько строк иногда разделяются переносом строки (\ n) - PullRequest
5 голосов
/ 10 апреля 2019

Я пытаюсь прочитать некоторые файлы Excel в пандах.В некоторых файлах интересующая таблица не полностью отформатирована, т.е. несколько строк форматируются как одна строка, но каждая такая строка имеет несколько строк.Таким образом, данные выглядят нормально при просмотре файла Excel.Также при анализе с использованием панд в конце каждой такой строки действительно есть символ новой строки (\ n).

Проблема в том, что когда я читаю его с помощью функции read_excel (), он преобразует его в DataFrame, который не считает этот разрыв строки отдельной строкой, а помещает его в одну строку с \ n.Я хотел бы написать код, который обрабатывает / конвертирует каждую такую ​​строку с N строками как N строками (используя разрывы строк как индикатор для новой строки).

Есть ли способ сделать это либо при синтаксическом анализе файла, либо при последующей обработке кадра данных в Python?

Здесь я приведу очень упрощенную версию моего фиктивного файла Excel и некоторый код дляобъясните проблему.

Образец Excel-файла:

Name                | Price
-------------------------------
Coca Cola           |     46.66
-------------------------------
Google              |   1204.44
Facebook            |    177.58
-------------------------------
Berkshire Hathaway  | 306513.75

Я просто использую read_excel Панда в Python:

dataframe_parsed = pandas.read_excel(file_name)
print(dataframe_parsed.head())

Я получаю следующий DataFrame в качестве вывода:

                 Name            Price
0           Coca Cola            46.66
1    Google\nFacebook  1204.44\n177.58
2  Berkshire Hathaway        306513.75

Желаемый результат:

                 Name           Price
0           Coca Cola           46.66
1              Google         1204.44
2            Facebook          177.58
3  Berkshire Hathaway       306513.75

Любая помощь будет высоко оценена.

Ответы [ 2 ]

4 голосов
/ 10 апреля 2019

После split вы можете проверить с помощью unnesting

yourdf=unnesting(df.apply(lambda x : x.str.split(r'\\n')),['Name','Price'])
yourdf
Out[50]: 
                 Name      Price
0           Coca Cola      46.66
1              Google    1204.44
1            Facebook     177.58
2  Berkshire Hathaway  306513.75

def unnesting(df, explode):
    idx = df.index.repeat(df[explode[0]].str.len())
    df1 = pd.concat([
        pd.DataFrame({x: np.concatenate(df[x].values)}) for x in explode], axis=1)
    df1.index = idx

    return df1.join(df.drop(explode, 1), how='left')

Так как вы упомянули выше, не работает

df.apply(lambda x : x.str.split(r'\\n')).stack().apply(pd.Series).stack().unstack(level=1).reset_index(drop=True)
Out[57]: 
                 Name      Price
0           Coca Cola      46.66
1              Google    1204.44
2            Facebook     177.58
3  Berkshire Hathaway  306513.75
0 голосов
/ 11 апреля 2019

Спасибо WenBen за вашу помощь.Но я не смог заставить ваш код выдавать желаемый результат.Однако, используя вашу ссылку unnesting , я нашел решение с некоторой помощью из ответа @ user3483203 на этой странице.Я опубликую решение здесь, на случай, если оно поможет кому-то, столкнувшемуся с подобной проблемой:

import pandas as pd
import numpy as np

def main():
    # Make a simple dummy dataframe for testing
    my_dataframe = pd.DataFrame({'ColA':["a1", "a2\na3", "a4\n a5 space"],'ColB':["b1", "b2\nb3","b4\nb5"]})
    print("DataFrame before:\n", my_dataframe.head())

    my_dataframe_after = myUnnesting(my_dataframe)
    print("DataFrame after:\n", my_dataframe_after.head())

def myUnnesting(dataframe):
    new_dataframe = pd.DataFrame()
    for column in dataframe:
        # Convert each column into an array of lists and concatenate these lists into a single array 
        col_vals = np.concatenate(np.array(dataframe[column].str.split("\n")))
        new_dataframe[column] = col_vals 

    return new_dataframe

if __name__ == "__main__":
    main()

Вывод:

DataFrame before:
             ColA    ColB
0             a1      b1
1         a2\na3  b2\nb3
2  a4\n a5 space  b4\nb5
DataFrame after:
         ColA ColB
0         a1   b1
1         a2   b2
2         a3   b3
3         a4   b4
4   a5 space   b5

Конечно, это решение предполагает, что для данной строки существуетравное число \ n в каждом столбце.Это предположение прекрасно работает для данных, которые я обрабатываю.Однако, если кто-то, читающий это, хотел бы опубликовать более общее решение, которое также работает с другими случаями, это будет высоко оценено.Благодарю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...