Конвертировать CSV с одним столбцом в несколько столбцов в Python - PullRequest
0 голосов
/ 14 октября 2019

У меня есть набор данных с одним столбцом и несколькими строками на элемент данных (количество строк на элемент данных не уникально). Элементы данных различаются строкой '-------------------------------'

Я хочуперенести данные в (3) столбцы. Данные должны быть разделены строкой '-------------------------------'

В идеале,первые два столбца должны быть идентификаторами, а остальная часть текста в любом количестве строк на элемент данных должна отображаться в один столбец, такой как id |id |текст

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

import csv
import sys
inp_fname = 'Comments.csv'
out_fname = 'Columned-Data.csv'

def rez(row, size):
    rowx = [''] * size
    for i in range(0,len(row)):
        rowx[i] = row[i]
    return rowx
MATCH = "-------------------------------\n"
cols = []
glob = []
with open(inp_fname, 'r', newline='') as in_csvfile, open(out_fname, 'w', newline='') as out_csvfile:
    reader = csv.reader(in_csvfile)
    writer = csv.writer(out_csvfile)
    for line in reader:
        if line == MATCH: 
            glob.append(list(cols))
            cols = []
        else:
            cols.append(line)
    MAX = max(map(lambda x: len(x), glob))

#output = list(map(lambda x: rez(x, MAX), glob))
#writer.writerow(output)
print(list(map(lambda x: rez(x, MAX), glob)))             

Мне нужно удалить строки '------------------------------- 'и включать только 3 строки (id, id, text) для каждого набора данных.

1 Ответ

0 голосов
/ 15 октября 2019

Мой исходный тестовый файл выглядит следующим образом:

r0 xxxx
r1 xxxx, yyy
r2 xxxx, zzz
--------
r3 xxxx
r4 xxxx
--------
r6 xxxx

Первый шаг - прочитать его с несуществующим разделителем (я выбрал '&' ), чтобы каждыйисходная строка - это содержимое поля single (я назвал его line ):

df = pd.read_csv('Input.txt', sep='&', names=['line'])

Следующим шагом является добавление столбца «группировки» в такое поле. способ, которым его значение увеличивается в каждой «точке контакта» между строкой, начинающейся с '----' (конец предыдущей «логической строки»), и следующей строкой, начинающейся с некоторого другого текста(начало следующей «логической строки»):

df['grp'] = (~df.line.str.startswith('----') & df.line.shift(fill_value='')\
    .str.startswith('----')).cumsum()

Результат для моих данных:

           line  grp
0       r0 xxxx    0
1  r1 xxxx, yyy    0
2  r2 xxxx, zzz    0
3      --------    0
4       r3 xxxx    1
5       r4 xxxx    1
6      --------    1
7       r6 xxxx    2

Следующим шагом является определение функции, генерирующей Серия строк, но без завершения '----' , из группы исходных строк:

def genRow(gr):
    return gr.loc[~gr.line.str.startswith('----'), 'line'].reset_index(drop=True)

Последний шаг ( reset_index ) было добавлено, чтобы индекс в результате всегда начинался с 0. Таким образом, когда результаты применения этой функции будут объединены, последовательные члены каждой группыup будет помещаться в последовательные столбцы, начиная с 0.

И для генерации конечного результата:

  • применить эту функцию к каждой группе,
  • unstack для создания DataFrame,
  • имя индекса удаления ( rename_axis ),
  • замена NaN s на пустые строки ( fillna).

Код для этого:

df2 = df.groupby('grp').apply(genRow).unstack(level=1).rename_axis('').fillna('')

Таким образом, мы получили:

         0             1             2
0  r0 xxxx  r1 xxxx, yyy  r2 xxxx, zzz
1  r3 xxxx       r4 xxxx              
2  r6 xxxx                            

Как видите:

  • Этот код работает, даже если в некоторых «логических строках» число строк (преобразованных в столбцы) меньше.
  • Любая строка может содержать, например, запятую, которая не разделяетИсходный текст в смежные поля.

В качестве последнего шага вы можете установить атрибут columns этого DataFrame, чтобы иметь имена столбцов по вашему желанию.

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