Pandas Dataframe - 更改数据结构(重新组织)

时间:2018-06-01 22:09:01

标签: python pandas dataframe data-structures

我读了一个包含这些数据的csv文件:

CatPart 1           
CodeItem    1           
12  15  
5.5 3   

CodeItem    2           
7   6   
2   7       

CatPart 5           
CodeItem    0           
1   25  
1.5 7   

CodeItem    8           
25  1   
22  1

我想在数据框中使用这种格式

CatPart CodeItem Weight Nb
1 1 12 15   
1 1 5.5 3       
1 2 7 6 
1 2 2 7 
5 0 1 25
5 0 1.5 7   
5 8 25  1
5 8 22  1

所以首先我用colums名称创建标题 df.columns = [" Weight"," Nb"," CatPart"," CodeItem"] 我删除了空行。我的策略是将CatPart行中的值复制到Cartpart列,这部分没问题(见下文),复制后将值替换为nan,直到下一个值(执行相同的CodeItem),然后删除CatPart行和CodeItem但我没有找到复制值的方法。

Weight      Nb  CatPart CodeItem
CatPart     1   1   nan
CodeItem    1   nan 1
12          15  nan nan
5.5         3   nan nan
CodeItem    2   2   nan
7           6   nan nan
2           7   nan nan
CatPart     5   5   nan
CodeItem    0   nan 0
1           25  nan nan
1.5         7   nan nan
CodeItem    8   8   nan
25          1   nan nan
22          1   nan nan

或者也许他们是一种更容易的方法,但我没有看到它。

感谢您的帮助! F。

1 个答案:

答案 0 :(得分:0)

这不是csv文件。

  • CatPartCodeItem更改时,它们会在行首处标记字段,后跟可变数量的空格,然后是值

  • weight& nb始终显示在由空格分隔的同一行上。

  • 当以下信息存在CatPartCodeItemweightnb时,可以认为记录已填写。

重构文档的一种方法是迭代行并在填充时生成记录。

import io
import re
import pandas as pd


text = """CatPart 1
CodeItem    1
12  15
5.5 3

CodeItem    2
7   6
2   7

CatPart 5
CodeItem    0
1   25
1.5 7
CodeItem    8
25  1
22  1"""

records = []
part, item, weight, nb = '', '', '', ''

for line in io.StringIO(text):
    if line.startswith('CatPart'):
        _, part = re.split('\s+', line.strip())
    if line.startswith('CodeItem'):
        _, item = re.split('\s+', line.strip())
    if re.match('^\d+', line):
        weight, nb = re.split('\s+', line.strip())
        records.append([part, item, weight, nb])

请注意,我已使用io.StringIO在此示例中为内存创建文件。用以下内容替换它:

with open('/path/to/my/file.txt') as in_file:
    for line in in_file:
        ...

然后将记录传递给pandas.DataFrame构造函数。

df = pd.DataFrame(records, columns=['CatPart', 'CatItem', 'weight', 'nb'])

产生以下输出:

  CatPart CatItem weight  nb
0       1       1     12  15
1       1       1    5.5   3
2       1       2      7   6
3       1       2      2   7
4       5       0      1  25
5       5       0    1.5   7
6       5       8     25   1
7       5       8     22   1

然而,在此之前,我没有从字符串转换任何数据。您可以在读取数据时进行转换,也可以在使用以下内容构建表中的数据后执行转换:

df = df.astype(float)