【问题标题】:Separate Column Name and Text & Pivot in Python在 Python 中分离列名和文本 & Pivot
【发布时间】:2020-06-04 04:22:23
【问题描述】:

我有一个带有分隔符的超级凌乱的 .txt 文件 |我想读入python。现在,它的结构是这样的:

Name: Name1
Location: Location1
Address: Address1
...
|
Name: Name2
Location: Location2
Address: Address2
...
|
Name: Name3
Location: Location3
Address: Address3
...
|

等等。 每个条目有 164 个“列”,整个内容现在大约有 250 万行。我需要用分隔符分隔这些条目 |以我猜的垂直方式?然后找出一种方法将列名分配为列名 once 并包含其下方的所有条目。

到目前为止我写的:

import pandas as pd

extract = pd.read_csv(r'myfile',
            encoding='utf8', sep='\|', index_col=False, names=['A'])

extract = extract.dropna()

to_drop = ["way too many strings aka columns I don't need because I couldn't figure out how to automate this"]

extract = extract[~extract['A'].str.contains('|'.join(to_drop))]

print(extract)

这会打印出我的专栏充满了废话,但我不知道如何做重要的“将内容分成列”位。

感谢您的帮助!

【问题讨论】:

  • 请包括您的预期输出

标签: python pandas


【解决方案1】:

使用; 或数据中不存在的其他分隔符读入数据,并将squeeze 读入一个系列。从这里开始,您可以拆分列并删除空行:

注意:我使用了read_clipboard,将 ith 替换为 read_csv,因为您拥有实际文件:

 df = (pd.read_clipboard(sep=";", squeeze=True)
       .str.split(":",expand=True)
       .dropna(how='any')
       )

df

         0       1
0   Location    Location1
1   Address     Address1
4   Name        Name2
5   Location    Location2
6   Address     Address2
9   Name        Name3
10  Location    Location3
11  Address     Address3

【讨论】:

    【解决方案2】:

    这个很有趣:)

    您可以使用lineterminatorsep 参数将换行符视为列,将管道视为行分隔符。这需要c 引擎,因此您将缺少一些功能,但您得到的是一个很好的起点:

    In [5]: df = pd.read_csv(
       ...:     fp,
       ...:     lineterminator='|',
       ...:     sep='\n',
       ...:     engine='c',
       ...:     header=None,
       ...:     names=['Name', 'Location', 'Address', 'offset'],
       ...: )
    
    In [6]: df
              Name             Location              Address             offset
    0  Name: Name1  Location: Location1    Address: Address1                NaN
    1          NaN          Name: Name2  Location: Location2  Address: Address2
    2          NaN          Name: Name3  Location: Location3  Address: Address3
    

    这很麻烦,但这是一个开始...您可以通过将 |\n 替换为 | 来修改源数据,但您也可以将第 1 行以上的行替换为:

    In [7]: df.iloc[1:, :-1] = df.iloc[1:, 1:].values
    In [8]: df = df.iloc[:, :-1]
    In [9]: df
              Name             Location            Address
    0  Name: Name1  Location: Location1  Address: Address1
    1  Name: Name2  Location: Location2  Address: Address2
    2  Name: Name3  Location: Location3  Address: Address3
    

    现在您可以使用字符串操作清理列,例如:

    In [10]: for col in df.columns:
        ...:     df[col] = df[col].str.extract(rf'{col}: (.*)', expand=False)
        ...:
    In [11]: df
        Name   Location   Address
    0  Name1  Location1  Address1
    1  Name2  Location2  Address2
    2  Name3  Location3  Address3
    

    希望有帮助!

    【讨论】:

    • 啊,是的,如果您不知道数据中的顺序或完整列集,那么 @sammywemmy 的 answer 可能会更好。
    猜你喜欢
    • 1970-01-01
    • 2015-11-02
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    • 1970-01-01
    • 2020-06-19
    • 2015-05-02
    • 1970-01-01
    相关资源
    最近更新 更多