如何使用 numpy 将文本文件细分为几个单独的数组

How to subdivide a textfile into several separate arrays with numpy

我有一个文本文件,我想根据其中一行中的值将其细分为 3 个单独的文本文件。如果 LineID 为 1,我想将具有该 LineID 的所有行移动到单独的数组甚至单独的文本文件中。

文本文件输出:

Num  LineID  ColA  ColB ColC
1 1 7 3.5 89.9
1 2 6.8 3.1 90.02
1 3 7.5 2.9 90
2 1 7.2 3.2 92
2 2 7.1 3.1 89.8
2 3 6.9 2.87 88
3 1 7.3 2.9 90
3 2 7.03 3.04 90
3 3 7.2 3 89.6

我想根据 LineID 值分成三个单独的数组或文本文件。

LineID 的第一个数组 = 1

Num  LineID  ColA  ColB ColC
1 1 7 3.5 89.9
2 1 7.2 3.2 92
3 1 7.3 2.9 90

LineID=2 的第二个数组

Num  LineID  ColA  ColB ColC
1 2 6.8 3.1 90.02
2 2 7.1 3.1 89.8
3 2 7.03 3.0 4 90

LineID=3 的第三个数组

Num  LineID  ColA  ColB ColC
1 3 7.5 2.9 90
2 3 6.9 2.87 88
3 3 7.2 3 89.6

有没有人在 python 或 Numpy/Pandas 中得到任何关于如何执行此操作的指示?

Ivan 提供了一个很好的解决方案,我还没有检查它们,它只是在每一行的开头添加了一个额外的数字,该数字对应于原始 array/text 文件中该行的原始位置。我已经用','和''分隔的csv和space分隔的txt文件进行了尝试,结果是一样的。

   Num  LineID  ColA  ColB  CoLC
0    1       1   7.0   3.5  89.9
3    2       1   7.2   3.2  92.0
6    3       1   7.3   2.9  90.0
   Num  LineID  ColA  ColB   CoLC
1    1       2  6.80  3.10  90.02
4    2       2  7.10  3.10  89.80
7    3       2  7.03  3.04  90.00
   Num  LineID  ColA  ColB  CoLC
2    1       3   7.5  2.90  90.0
5    2       3   6.9  2.87  88.0
8    3       3   7.2  3.00  89.6

根据您的文本文件将被命名为 example.txt,包含以下内容:

Num  LineID  ColA  ColB ColC
1 1 7 3.5 89.9
1 2 6.8 3.1 90.02
1 3 7.5 2.9 90
2 1 7.2 3.2 92
2 2 7.1 3.1 89.8
2 3 6.9 2.87 88
3 1 7.3 2.9 90
3 2 7.03 3.04 90
3 3 7.2 3 89.6

您可以使用 pandas 将其作为 DataFrame 导入:

import pandas as pd
df = pd.read_csv('example.txt', sep=' ')

然后你可以过滤行号:

df1 = df[df.LineID == 1]
...

这应该有帮助,id1、id2 和 id3 都有你需要的,你可以稍后用它们各自写一个文件。

import pandas as pd

data = pd.read_csv('textfile.txt', sep=" ")
id1 = data[data['LineID'] == 1]
id2 = data[data['LineID'] == 2]
id3 = data[data['LineID'] == 3]

print(id1)
print(id2)
print(id3)

groupbyto_csv

  • 一定要包含选项 index=False 以表明您不想在输出中包含索引。
  • 请不要手动搜索每个唯一的 'LineID' 并根据等于它的值对 DataFrame 进行子集化。使用 groupby!
  • 此外,您可以像字典一样非常优雅地遍历 groupby 对象。这就是我在下面所做的。

for lid, grp in df.groupby('LineID'):
    grp.to_csv(f'text_{lid}.csv', index=False, sep=' ')

验证

from pathlib import Path

for fp in Path('.').glob('text_*.csv'):
    print(fp)
    print('-' * 80)
    print(open(fp).read())
    print()

text_1.csv
--------------------------------------------------------------------------------
Num LineID ColA ColB ColC
1 1 7.0 3.5 89.9
2 1 7.2 3.2 92.0
3 1 7.3 2.9 90.0


text_2.csv
--------------------------------------------------------------------------------
Num LineID ColA ColB ColC
1 2 6.8 3.1 90.02
2 2 7.1 3.1 89.8
3 2 7.03 3.04 90.0


text_3.csv
--------------------------------------------------------------------------------
Num LineID ColA ColB ColC
1 3 7.5 2.9 90.0
2 3 6.9 2.87 88.0
3 3 7.2 3.0 89.6

dict DataFrame 作者 'LineID'

dict_of_df_by_lid = dict((*df.groupby('LineID'),))
# Less Obtuse
# dict_of_df_by_lid = {k: v for k, v in df.groupby('LineID')}

验证

for k, v in dict_of_df_by_lid.items():
    print(f'LineID: {k}')
    print('-' * 80)
    print(v)
    print()

LineID: 1
--------------------------------------------------------------------------------
   Num  LineID  ColA  ColB  ColC
0    1       1   7.0   3.5  89.9
3    2       1   7.2   3.2  92.0
6    3       1   7.3   2.9  90.0

LineID: 2
--------------------------------------------------------------------------------
   Num  LineID  ColA  ColB   ColC
1    1       2  6.80  3.10  90.02
4    2       2  7.10  3.10  89.80
7    3       2  7.03  3.04  90.00

LineID: 3
--------------------------------------------------------------------------------
   Num  LineID  ColA  ColB  ColC
2    1       3   7.5  2.90  90.0
5    2       3   6.9  2.87  88.0
8    3       3   7.2  3.00  89.6

如果初始文件很大,或者想节省内存,打开的文件可以比FileID多,甚至可以用csv模块一次一行处理。

假设初始文件是 file.txt 并且您想将其拆分为几个 file_i.txt 文件,其中 i 是 LineID:

import csv

ident = 'LineID'
with open('file.txt') as fdin:
    files = {}                # to store the output files and writers
    rd = csv.DictReader(fdin, delimiter=' ', skipinitialspace=True)
    for row in rd:
        if not row[ident] in files:    # found a new LineID
            fout = open('file_{}.txt'.format(row[ident]), 'w', newline='') # create the file
            wr = csv.DictWriter(fout, rd.fieldnames)                       # and the associated writer
            wr.writeheader()                                               # write the header
            files[row[ident]] = (wr, fout)                                 # store everything in files
        files[row[ident]][0].writerow(row)              # write each row to the appropriate file

# close the output files
for id in files:
    files[id][1].close()