преобразовать список в фрейм данных, используя словарь - PullRequest
0 голосов
/ 02 марта 2019

Я новичок в Pythonland и у меня есть вопрос.У меня есть список, как показано ниже, и я хочу преобразовать его в фрейм данных.

Я прочитал в Stackoverflow, что лучше создать словарь, чем список, поэтому я создаю его следующим образом.

column_names = ["name", "height" , "weight", "grade"] # Actual list has 10 entries

row_names = ["jack", "mick", "nick","pick"]

data = ['100','50','A','107','62','B'] # The actual list has 1640 entries

dic = {key:[] for key in column_names}
dic['name'] = row_names
t = 0
while t< len(data):
    dic['height'].append(data[t])
    t = t+3
t = 1
while t< len(data):
    dic['weight'].append(data[t])
    t = t+3

Итак, у меня есть 10 столбцов, поэтому я написал код 10 раз, чтобы завершить полный словарь.Затем я конвертирую его в датафрейм.Он отлично работает, должен быть способ сделать это более коротким способом.Я не знаю, как ссылаться на ключ словаря с номером.Должен ли он быть обернут в функцию.Кроме того, как я могу автоматизировать добавление одного к значению t перед выполнением следующего цикла?Пожалуйста, помогите мне.

Ответы [ 5 ]

0 голосов
/ 02 марта 2019

Если вы используете Python 3.x, как предложено l159 , вы можете использовать диктант понимания, а затем создать из него DataFrame Pandas, используя имена в качестве индексов строк:

data = ['100', '50', 'A', '107', '62', 'B', '103', '64', 'C', '105', '78', 'D']
column_names = ["height", "weight", "grade"]
row_names = ["jack", "mick", "nick", "pick"]

df = pd.DataFrame.from_dict(
    {
        row_label: {
            column_label: data[i * len(column_names) + j]
            for j, column_label in enumerate(column_names)
        } for i, row_label in enumerate(row_names)
    },
    orient='index'
)

На самом деле промежуточный словарь является вложенным словарем: ключи внешнего словаря являются метками строк (в данном случае это элементы списка row_names);значение, связанное с каждым ключом, является словарем, ключи которого являются метками столбцов (т. е. элементы в column_names), а значения являются соответствующими элементами в списке data.

Функция from_dict используется для создания экземпляра DataFrame.

Итак, предыдущий код дает следующий результат:

     height weight grade
jack    100     50     A
mick    107     62     B
nick    103     64     C
pick    105     78     D
0 голосов
/ 02 марта 2019

Во-первых, мы должны понять, как должен выглядеть идеальный словарь для фрейма данных.

Фрейм данных можно представить двумя разными способами:
Один - это традиционный набор строк..

'row 0':  ['jack', 100, 50, 'A'],
'row 1':  ['mick', 107, 62, 'B']

Однако есть второе представление, которое более полезно, хотя поначалу, возможно, и не так интуитивно понятно.
Набор столбцов:

'name': ['jack', 'mick'],
'height': ['100', '107'],
'weight': ['50', '62'],
'grade': ['A', 'B']

Теперь вот ключевая вещь, которую нужно осознать, 2-е представление более полезно, потому что это представление, которое поддерживается и используется во фреймах данных.
Оно не сталкивается с конфликтом типов данных в пределах одной группировки (каждый столбец должен иметь 1 фиксированный тип данных) Однако в представлении строки типы данных могут различаться.
Кроме того, операции могут выполняться легко и согласованно для всего столбца из-за этой согласованности, которую нельзя гарантировать в строке.

Итак, tl; dr DataFrames по сути являются коллекциями столбцов одинаковой длины.

Итак, словарь в этом представлении можно легко преобразовать в DataFrame.

column_names = ["name", "height" , "weight", "grade"] # Actual list has 10 entries

row_names = ["jack", "mick"]

data = [100, 50,'A', 107, 62,'B'] # The actual list has 1640 entries

Итак, с учетом этого, первое, что нужно понять, это то, что в его текущем форматеdata - очень плохое представление. Это набор строк, объединенных в один список.

Первое, что нужно сделать, если вы сами контролируете, как формируются данные, - это не подготовить их таким образом.

Цель - создать список для каждого столбца, ив идеале, подготовьте список в этом формате.

Теперь, однако, если он задан в этом формате, вам нужно выполнить итерацию и собрать значения соответствующим образом.Вот способ сделать это

column_names = ["name", "height" , "weight", "grade"] # Actual list has 10 entries
row_names = ["jack", "mick"]
data = [100, 50,'A', 107, 62,'B'] # The actual list has 1640 entries

dic = {key:[] for key in column_names}
dic['name'] = row_names
print(dic)

Вывод до сих пор:

{'height': [],
 'weight': [],
 'grade': [],
 'name': ['jack', 'mick']} #so, now, names are a column representation with all correct values.

remaining_cols = column_names[1:]

#Explanations for the following part given at the end
data_it = iter(data)
for row in zip(*([data_it] * len(remaining_cols))):
    for i, val in enumerate(row):
        dic[remaining_cols[i]].append(val)

print(dic)

Вывод:

{'name': ['jack', 'mick'],
 'height': [100, 107],
 'weight': [50, 62],
 'grade': ['A', 'B']}

И мы закончили с представлением

Наконец:

import pd
df = pd.DataFrame(dic, columns = column_names)
print(df)
   name  height  weight grade
0  jack     100      50     A
1  mick     107      62     B

Редактировать: Некоторое объяснение части zip: zip берет любые итерации и позволяет нам проходить через них вместе.

data_it = iter(data) #prepares an iterator. 

[data_it] * len(remaining_cols) #creates references to the same iterator

Здесь этоаналогично [data_it, data_it, data_it]

* в *[data_it, data_it, data_it] позволяет нам вместо этого распаковать список в 3 аргумента для функции zip, поэтому f(*[data_it, data_it, data_it]) эквивалентно f(data_it, data_it, data_it) для любой функции f.

магия здесь в том, что прохождение итератора / продвижение итератора теперь будет отражать изменение по всем ссылкам

Собрав все это вместе: zip(*([data_it] * len(remaining_cols))) фактически позволит нам взять 3 элемента из данныхи назначьте его в строку Итак, row = (100, 50, 'A') в первой итерации zip

for i, val in enumerate(row): #just iterate through the row, keeping index too using enumerate
    dic[remaining_cols[i]].append(val) #use indexes to access the correct list in the dictionary

Надеюсь, это поможет.

0 голосов
/ 02 марта 2019
i = 0
while True:
    try:
        for j in column_names:
            d[j].append(data[i])
            i += 1

    except Exception as er:  #So when i value exceed by data list it comes to exception and it will break the loop as well
        print(er, "################")
        break
0 голосов
/ 02 марта 2019

Первая проблема, при которой все данные столбцов объединяются в один список.Сначала вы должны выяснить, как это предотвратить, и составить список списков со значениями каждого столбца в отдельном списке, например [['100', '107'], ['50', '62'], ['A', 'B']].В любом случае, чтобы эта структура данных работала эффективно, вам нужно:

cl_count = len(column_names)
d_count = len(data)
spl_data = [[data[j] for j in range(i, d_count, cl_count)] for i in range(cl_count)] 

Тогда вам следует использовать диктетное понимание. Это 3.x функция Python , поэтому она не будет работать в Py 2.x.

df = pd.DataFrame({j: spl_data[i] for i, j in enumerate(column_names)})
0 голосов
/ 02 марта 2019

Вы можете перебирать columnn_names следующим образом:

dic = {key:[] for key in column_names}
dic['name'] = row_names
for t, column_name in enumerate(column_names):
    i = t
    while i< len(data):
        dic[column_name].append(data[i])
        i += 3

Перечислять будут автоматически перебирать t форму от 0 до len(column_names)-1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...