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

2024-05-21 03:18:41 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我想把数据转换成(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,text)。你知道吗


Tags: csv数据csvfileinidoutfnameglob
1条回答
网友
1楼 · 发布于 2024-05-21 03:18:41

我的源测试文件如下:

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

第一步是使用不存在的分隔符读取它(我选择了'&;'), 所以每个源代码行都是一个单个字段的内容(我将其命名为 ):

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

下一步是添加“grouping”列,使其值 从''开始的线之间的每个“接触点”增加 (上一个“逻辑行”的结尾)和下一行以 其他一些文本(从下一个“逻辑行”开始):

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)

最后一步(重置索引)被添加到始终在结果中有索引 从0开始。 这样,当应用此函数的结果将被串联时, 每个组的连续成员将放入连续的列中, 从0开始。你知道吗

并生成最终结果:

  • 将此函数应用于每个组
  • 取消堆叠以创建数据帧
  • 删除索引名称(重命名\u轴
  • 用空字符串(fillna)替换NaNs。你知道吗

执行此操作的代码是:

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                            

如你所见:

  • 即使某些“逻辑行”中的行数 (转换为列)更小。你知道吗
  • 任何一行都可以包含一个逗号,它不能分隔 将源文本插入相邻字段。你知道吗

最后一步,您可以设置此数据帧的属性, 如您所愿拥有列名。你知道吗

相关问题 更多 >