Как разделить текстовый файл на несколько отдельных массивов с numpy - PullRequest
1 голос
/ 10 января 2020

У меня есть текстовый файл, который я хотел бы разделить на 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?

Иван предложил хорошее решение, я не проверил их все еще, он просто добавляет дополнительный номер в начале каждой строки, который соответствует исходной позиции этой строки в исходном массиве / текстовом файле. Я попробовал его с разделенными символами ',' и '' текстовыми файлами с разделителями csv и пробелами, и все получилось одинаково.

   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

Ответы [ 4 ]

2 голосов
/ 10 января 2020

В соответствии с тем, что ваш текстовый файл будет иметь имя 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=' ')

Тогда вы можете отфильтровать по строке id:

df1 = df[df.LineID == 1]
...
1 голос
/ 10 января 2020

groupby и to_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
1 голос
/ 10 января 2020

Это должно помочь, 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)
0 голосов
/ 10 января 2020

Если исходный файл большой или если вы хотите сэкономить память и у вас может быть больше открытых файлов, чем 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...