Использование целых чисел из отдельного файла для группировки столбцов в фрейме данных pandas

#python #pandas

#python #pandas

Вопрос:

Я хочу использовать целые числа в одном файле, чтобы соответствующим образом называть столбцы в другом файле. Например:

Файл 1

 3 2 3 3 3 2
  

Файл 2

 0.2 0.0 0.0 1.0 0.98 0.98 0.02 0.02 0.97 
0.4 0.4 0.3 2.0 0.30 0.03 0.30 0.93 0.39
  

Первое целое число в File1 равно 3, поэтому в File2 я хочу обозначить первые три столбца (после столбца 0) как 0_1, 0_2, 0_3 . Второе целое число в File1 равно 2, поэтому будут обозначены следующие два столбца в File2 1_1, 1_2 .

Ожидаемый результат:

   time  0_1  0_2  0_3   1_1   1_2   2_1   2_2   2_3   
   0.2  0.0  0.0  1.0  0.98  0.98  0.02  0.02  0.97 
   0.4  0.4  0.3  2.0  0.30  0.03  0.30  0.93  0.39
  

Когда я назначаю индексы следующим образом, я просто заканчиваю тем, что столбцы пронумерованы одинаково — есть ли способ добиться желаемого результата?

 import pandas as pd
import numpy as np
import sys

file1 = "nsubs"
new = ['time']

file2 = sys.argv[1]

df = pd.read_csv(file1, sep=" ", header=None)
num = df.iloc[0].values.tolist()
for idx, item in enumerate(num):
    if item == 3:
        new.append(idx)
        new.append(idx[2])
        new.append(idx)
    else:
        new.append(idx)
        new.append(idx)

df2 = pd.read_csv(file2, sep=" ", header=None)
df2.columns = [new]
  

Фактический результат:

   time    0    0    0     1     1     2     2     2 
   0.2  0.0  0.0  1.0  0.98  0.98  0.02  0.02  0.97 
   0.4  0.4  0.3  2.0  0.30  0.03  0.30  0.93  0.39
  

Ответ №1:

С имеющимися у вас данными вам действительно не нужны pandas для заголовков столбцов. Вы можете прочитать их в список и выполнить над ними понимание списка, чтобы получить свои заголовки.

Прочитайте текстовый файл, используйте функцию разделения, чтобы разделить их, а затем преобразуйте их в целые числа

 with open('file1.txt', 'r') as f:
    column_counts = [int(i) for i in f.read().split()]
# [3, 2, 3, 3, 3, 2]
  

Затем вам просто нужно создать простой цикл. Используйте enumerate() , как и для подсчета набора, и значение для подмножества следующих нескольких столбцов. Цикл for показан для демонстрации, но я предлагаю использовать понимание списка.

 colums = ['time']
for i, n in enumerate(column_counts):
    for j in range(1, n 1):
        columns.append("{}_{}".format(i, j))

columns = ['time']   ["{}_{}".format(i, j) for i, n in enumerate(column_counts) for j in range(1, n 1)]
#['time', '0_1', '0_2', '0_3', '1_1', '1_2', '2_1', '2_2', '2_3', '3_1', '3_2', '3_3', '4_1', '4_2', '4_3', '5_1', '5_2']
  

В вашем примере file1 получается гораздо более длинный список столбцов, чем file2 , поэтому мне пришлось вырезать их, как только я узнал, сколько столбцов требуется для фрейма данных. Если ваши данные совпадают, вы можете использовать columns=columns их при создании фрейма данных.

 df = pd.read_csv('file2.txt', sep=" ", header=None)
df.columns = columns[:len(df.columns)]
df.set_index('time', inplace=True)

print(df)
#       0_1  0_2  0_3   1_1   1_2   2_1   2_2   2_3
# time                                             
# 0.2   0.0  0.0  1.0  0.98  0.98  0.02  0.02  0.97
# 0.4   0.4  0.3  2.0  0.30  0.03  0.30  0.93  0.39
  

Комментарии:

1. Я действительно ценю расширенное объяснение — спасибо!