Во-первых, мы должны понять, как должен выглядеть идеальный словарь для фрейма данных.
Фрейм данных можно представить двумя разными способами:
Один - это традиционный набор строк..
'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
Надеюсь, это поможет.