Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中将具有一列的CSV转换为多列_Python_Regex_Pandas_Csv - Fatal编程技术网

在Python中将具有一列的CSV转换为多列

在Python中将具有一列的CSV转换为多列,python,regex,pandas,csv,Python,Regex,Pandas,Csv,我有一个数据集,每个数据项有一列和几行(每个数据项的行数不是唯一的)。数据项由一行“------------------------------------”区分 我想将数据转换为(3)列。数据应按“------------------------------------”行分割 理想情况下,前两列应该是id,每个数据项的行数中的其余文本应该映射到id | id | text这样的一列 我尝试了SO中建议的不同方法,但仍然无法获得所需的输出 import csv import sys inp_f

我有一个数据集,每个数据项有一列和几行(每个数据项的行数不是唯一的)。数据项由一行“------------------------------------”区分

我想将数据转换为(3)列。数据应按“------------------------------------”行分割

理想情况下,前两列应该是id,每个数据项的行数中的其余文本应该映射到id | id | text这样的一列

我尝试了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、文本)。

我的源测试文件如下:

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                            
如你所见:

  • 即使在某些“逻辑行”中的行数 (转换为列)较小
  • 任何一行都可以包含例如逗号,它不会分隔 将源文本插入相邻字段
作为最后一步,您可以设置此数据帧的columns属性,
如您所愿使用列名。

此数据集无法使用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