#python #pandas #dataframe #csv
#python #pandas #dataframe #csv
Вопрос:
У меня есть файл csv, в котором содержится неравномерное количество столбцов. В одном столбце указано число, которое указывает, сколько дополнительных столбцов содержит эта строка. Этот столбец «num_servers» и является целым числом. За этим столбцом следует один сервер и один столбец портов для каждого num_server, т.Е. «host_0», «port_0», «host_1», «port_1» для num_server = 2.
Я хочу объединить эти столбцы, в которых есть данные, т.Е. Сервер, порт и заполнить None / Nan, где их нет, чтобы у меня был единый фрейм данных, в котором только столбцы в середине содержат Nones, и в итоге получился фрейм данных.
Пример csv:
sym1,exch,3,server_a,port_a,server_a,port_b,server_f,port_f,info1,info2,info3
sym2,exch,1,server_a,port_a,info1,info2,info3
sym3,exch,0,info1,info2,info3
sym4,exch,2,server_a,port_a,server_d,port_c,info1,info2,info3
Словарь фрейма данных pandas, который мне понадобится, это:
d = {"a": ["sym1", "sym2", "sym3", "sym4"], "b": ["blah", "blah", "blah", "blah"], "num_servers": [3, 1, 0, 2], "loc_0": ["server_a,port_a", "server_a,port_a", None, "server_a,port_a"], "loc_1": ["server_a,port_b", None, None, "server_d,port_c"], "loc_2": ["server_f,port_f", None, None, None], "info_1": ["info_1", "info_1", "info_1", "info_1"], "info_2": ["info_2", "info_2", "info_2", "info_2"], "info_3": ["info_3", "info_3", "info_3", "info_3"]}
Когда это находится в конце файла, легко выполнить цикл от первого столбца до конца, потому что в каждом столбце без сервера уже есть Nones, но я не знаю, как справиться с этим в середине. К сожалению, перезапись файла конфигурации невозможна.
Комментарии:
1. Что вам нужно в качестве выходных данных? Фрейм данных или словарь? Не могли бы вы пояснить. Кроме того, я бы попросил вас восстановить как вопрос, так и заголовок, поскольку они не очень понятны.
2. Мне требуется фрейм данных, но словарь был простым способом отображения выходных данных. Конечно, можно попытаться перефразировать
Ответ №1:
Я бы использовал модуль csv для анализа файла, потому что он может легко обрабатывать переменное количество полей. Код может быть:
with open('file.csv') as fd:
rd = csv.reader(fd)
data = [] # will build a list of records as dicts
mx = 0
for row in rd:
num_servers = int(row[2])
if num_servers > mx: # keep the max number of servers
mx = num_servers
# build one record
d = {'a': row[0], 'b': row[1], 'num_servers': num_servers,
'info1': row[-3], 'info2': row[-2], 'info3': row[-3]}
for i in range(num_servers):
d['loc_' str(i)] = '{},{}'.format(row[3 i * 2], row[4 i * 2])
data.append(d) # add the record to the list
cols = ['a', 'b', 'num_servers'] # build the list of columns
cols.extend('loc_' str(i) for i in range(mx))
cols.extend(('info1', 'info2', 'info3'))
df = pd.DataFrame(data, columns=cols) # done...
В примере файла это дает:
a b num_servers loc_0 loc_1 loc_2 info1 info2 info3
0 sym1 exch 3 server_a,port_a server_a,port_b server_f,port_f info1 info2 info1
1 sym2 exch 1 server_a,port_a NaN NaN info1 info2 info1
2 sym3 exch 0 NaN NaN NaN info1 info2 info1
3 sym4 exch 2 server_a,port_a server_d,port_c NaN info1 info2 info1
Комментарии:
1. Это работает замечательно, опечатка в последнем «info3» должна быть -1, но в остальном работает блестяще