Построение pandas DataFrame из значений в переменных дает «ValueError: Если вы используете все скалярные значения, вы должны передать индекс»

370

Это может быть простой вопрос, но я не могу понять, как это сделать. Допустим, у меня есть две переменные следующим образом.

a = 2
b = 3

Я хочу построить DataFrame из этого:

df2 = pd.DataFrame({'A':a,'B':b})

Это приводит к ошибке:

ValueError: Если используются все скалярные значения, вы должны передать индекс

Я попробовал это также:

df2 = (pd.DataFrame({'a':a,'b':b})).reset_index()

Это дает то же сообщение об ошибке.

Нилани Алгириаге
источник

Ответы:

572

Сообщение об ошибке говорит, что если вы передаете скалярные значения, вы должны передать индекс. Таким образом, вы можете либо не использовать скалярные значения для столбцов - например, использовать список:

>>> df = pd.DataFrame({'A': [a], 'B': [b]})
>>> df
   A  B
0  2  3

или используйте скалярные значения и передайте индекс:

>>> df = pd.DataFrame({'A': a, 'B': b}, index=[0])
>>> df
   A  B
0  2  3
DSM
источник
7
Возможно, это связано с тем, что порядок элементов в списке в Python является постоянным, а порядок элементов в словаре - нет. Вы можете создать экземпляр DataFrame с пустым словарем. В принципе, я предполагаю, что однострочный DataFrame, как показано здесь, также будет приемлем для построения из словаря, потому что порядок не имеет значения (но это не было реализовано). Однако с несколькими строками Pandas не сможет создать DataFrame, потому что он не будет знать, какие элементы принадлежат одной и той же строке.
Александр
2
@VitalyIsaev - В этом случае строка данных (представленная данным словарем) не имеет индекса (даже неявного). Простое решение - заключить словарь в список, который имеет «естественную индексацию». Можно утверждать, что если дан только один словарь (без списка переноса), то предположим index=0, но это может привести к случайному неправильному использованию (думая, что один словарь может каким-то образом создать многострочный фрейм данных)
Ori
несколько решений по этой ссылке eulertech.wordpress.com/2017/11/28/…
Джейсон Гол
Причина этого в том, что DataFrames предназначены для хранения двумерных данных (то есть строк двух переменных OP). Если вы хотите просто сохранить пары индекс -> значение (например, словарь), то вам следует использовать Series, как предлагает Роб .
Данукер
Это отдельный образец / строка Dataframe, поэтому index = [0] имеет логический смысл; но вы также можете манипулировать им, чтобы он был index = [100], что работает. Q: Разве Индекс не должен логически упорядочиваться по порядку, почему Python допускает манипулирование Индексом?
Сумант Лазарь
65

Вы также можете использовать, pd.DataFrame.from_recordsчто более удобно, когда у вас уже есть словарь:

df = pd.DataFrame.from_records([{ 'A':a,'B':b }])

Вы также можете установить индекс, если хотите, следующим образом:

df = pd.DataFrame.from_records([{ 'A':a,'B':b }], index='A')
факс
источник
27
Этот ответ не работает для меня - я получаю то же сообщение об ошибке при использовании from_records.
Дэйв Келпински
Дэйв, ты пробовал кусок кода (определите a и b, конечно)? Вы все еще получаете сообщение об ошибке? Вы можете опубликовать?
ФАКС
12
@DaveKielpinski Возможно, вы забыли добавить скобки?
Деннис
Это будет использовать ключи DICT в качестве имен столбцов. Как установить ключи для индексации?
Минчау
@DaveKielpinski Пожалуйста, проверьте, передали ли вы список методу from_records; в противном случае это не сработает, и вы получите то же сообщение об ошибке, что и при вызове DataFrame в словаре.
Майран
55

Вы должны сначала создать серию панд. Второй шаг - преобразование серии панд в фрейм данных панд.

import pandas as pd
data = {'a': 1, 'b': 2}
pd.Series(data).to_frame()

Вы даже можете указать имя столбца.

pd.Series(data).to_frame('ColumnName')
MLguy
источник
1
Это сработало для меня. В моем словаре были целочисленные ключи и значения ndarray.
StatsSorceress
pd.Series(data).to_frame('ColumnName')короче, хотя этот эквивалент, возможно, более прямой:pd.DataFrame.from_dict(data, orient='index', columns=['ColumnName'])
Алекс Ф
29

Вы можете попробовать обернуть свой словарь в список

my_dict = {'A':1,'B':2}

pd.DataFrame([my_dict])

   A  B
0  1  2
NewBie
источник
8

Возможно, Series предоставит вам все необходимые функции:

pd.Series({'A':a,'B':b})

DataFrame можно рассматривать как коллекцию Series, поэтому вы можете:

  • Объединить несколько серий в один фрейм данных (как описано здесь )

  • Добавьте переменную Series в существующий фрейм данных ( пример здесь )

обкрадывать
источник
7

Вам необходимо предоставить итерации в качестве значений для столбцов Pandas DataFrame:

df2 = pd.DataFrame({'A':[a],'B':[b]})
Ely
источник
6

У меня была такая же проблема с массивами numpy, и решение состоит в том, чтобы сгладить их:

data = {
    'b': array1.flatten(),
    'a': array2.flatten(),
}

df = pd.DataFrame(data)
MicheleDIncecco
источник
3

Если вы намереваетесь преобразовать словарь скаляров, вы должны включить индекс:

import pandas as pd

alphabets = {'A': 'a', 'B': 'b'}
index = [0]
alphabets_df = pd.DataFrame(alphabets, index=index)
print(alphabets_df)

Хотя индекс не требуется для словаря списков, эту же идею можно расширить до словаря списков:

planets = {'planet': ['earth', 'mars', 'jupiter'], 'length_of_day': ['1', '1.03', '0.414']}
index = [0, 1, 2]
planets_df = pd.DataFrame(planets, index=index)
print(planets_df)

Конечно, для словаря списков вы можете построить фрейм данных без индекса:

planets_df = pd.DataFrame(planets)
print(planets_df)
k0L1081
источник
3

Вы можете попробовать:

df2 = pd.DataFrame.from_dict({'a':a,'b':b}, orient = 'index')

Из документации по аргументу 'orient': если ключи переданного dict должны быть столбцами результирующего DataFrame, передайте 'columns' (по умолчанию). В противном случае, если ключи должны быть строками, передайте «index».

Мэтью Коннелл
источник
Пожалуйста, используйте инструменты форматирования, чтобы правильно редактировать и форматировать ваш вопрос / ответ. Коды в предложениях должны быть отформатированы как code очень важные слова, которые должны быть выделены жирным шрифтом , менее важные значения - курсивом. При необходимости также используйте списки
Морс
Это не решает поставленный вопрос, оно дает результат, отличный от желаемого.
Кен Уильямс
3

Магия панд на работе. Вся логика отсутствует.

Сообщение об ошибке "ValueError: If using all scalar values, you must pass an index"говорит, что вы должны передать индекс.

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

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

a = 2
b = 3
df2 = pd.DataFrame({'A':a,'B':b}, index=[1])

    A   B
1   2   3

Передача большего индекса:

df2 = pd.DataFrame({'A':a,'B':b}, index=[1, 2, 3, 4])

    A   B
1   2   3
2   2   3
3   2   3
4   2   3

Индекс обычно автоматически генерируется кадром данных, если он не указан. Тем не менее, панды не знает, сколько строк 2и 3вы хотите. Однако вы можете быть более откровенным об этом

df2 = pd.DataFrame({'A':[a]*4,'B':[b]*4})
df2

    A   B
0   2   3
1   2   3
2   2   3
3   2   3

Индекс по умолчанию равен 0, хотя.

Я бы рекомендовал всегда передавать словарь списков конструктору dataframe при создании кадров данных. Это легче читать для других разработчиков. У Pandas много предостережений, не заставляйте других разработчиков обращаться к экспертам во всех из них, чтобы прочитать ваш код.

firelynx
источник
3

входные данные не должны быть списком записей - это может быть также один словарь:

pd.DataFrame.from_records({'a':1,'b':2}, index=[0])
   a  b
0  1  2

Что, кажется, эквивалентно:

pd.DataFrame({'a':1,'b':2}, index=[0])
   a  b
0  1  2
С.В.
источник
2

Это потому, что DataFrame имеет два интуитивно понятных измерения - столбцы и строки.

Вы только указываете столбцы, используя ключи словаря.

Если вы хотите указать только одномерные данные, используйте Series!

danuker
источник
0

Преобразовать словарь в фрейм данных

col_dict_df = pd.Series(col_dict).to_frame('new_col').reset_index()

Дайте новое имя колонке

col_dict_df.columns = ['col1', 'col2']
Камран Каусар
источник
-2

Если у вас есть словарь, вы можете превратить его в фрейм данных Pandas со следующей строкой кода:

pd.DataFrame({"key": d.keys(), "value": d.values()})
Ingrid
источник
Это работает, но ИМХО это не имеет особого смысла <code> `<! - language: lang-py -> fruits_count = defaultdict (int) fruits_count [" яблок "] = 10 fruits_count [" бананы "] = 21 pd.DataFrame ({"key": fruits_count.keys (), "value": fruits_count.values ​​()}) Out: значение ключа 0 (бананы, яблоки) (21, 10) 1 (бананы, яблоки) (21, 10) <code>
Эмитер
-3

Просто передайте слово в списке:

a = 2
b = 3
df2 = pd.DataFrame([{'A':a,'B':b}])
LeandroHumb
источник