在Python中将具有一列的CSV转换为多列
我有一个数据集,每个数据项有一列和几行(每个数据项的行数不是唯一的)。数据项由一行“------------------------------------”区分 我想将数据转换为(3)列。数据应按“------------------------------------”行分割 理想情况下,前两列应该是id,每个数据项的行数中的其余文本应该映射到id | id | text这样的一列 我尝试了SO中建议的不同方法,但仍然无法获得所需的输出在Python中将具有一列的CSV转换为多列,python,regex,pandas,csv,Python,Regex,Pandas,Csv,我有一个数据集,每个数据项有一列和几行(每个数据项的行数不是唯一的)。数据项由一行“------------------------------------”区分 我想将数据转换为(3)列。数据应按“------------------------------------”行分割 理想情况下,前两列应该是id,每个数据项的行数中的其余文本应该映射到id | id | text这样的一列 我尝试了SO中建议的不同方法,但仍然无法获得所需的输出 import csv import sys inp_f
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、文本)。我的源测试文件如下:
r0 xxxx
r1 xxxx, yyy
r2 xxxx, zzz
--------
r3 xxxx
r4 xxxx
--------
r6 xxxx
第一步是使用不存在的分隔符(我选择了“&”)读取它,
因此,每个源行都是一个单个字段的内容(我将其命名为
行):
下一步是添加一个“分组”列,使其值
在以“----”开头的线之间的每个“接触点”上增加
(上一个“逻辑行”的结尾)和以
其他一些文本(下一个“逻辑行”的开头):
对于我的数据,结果是:
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)
最后一步(重置索引)被添加到始终在结果中具有索引
从0开始。
这样,当应用此函数的结果将被连接时,
每组的连续成员将放入连续的列中,
从0开始
并生成最终结果:
- 将此功能应用于每个组
- 取消堆栈以创建数据帧
- 删除索引名称(重命名_轴)
- 将NAN替换为空字符串(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
如你所见:
- 即使在某些“逻辑行”中的行数 (转换为列)较小
- 任何一行都可以包含例如逗号,它不会分隔 将源文本插入相邻字段
如您所愿使用列名。此数据集无法使用pandas的可能重复项,因为它有一些分隔符,代码会删除这些分隔符以使其正常工作。因此,这种方法不起作用。我正在寻找一个python解决方案。你介意发布一个最小的示例输入/预期输出吗?我正在尝试更新的代码。但是,将行与匹配项匹配存在一个问题。你能告诉我哪里出了问题吗?谢谢!我尝试了使用JSON解析进行数据提取,这个问题得到了解决。
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