关于python:从变量中的值构造pandas DataFrame给出“ValueError:如果使用所有标量值,则必须传递索引”

Constructing pandas DataFrame from values in variables gives “ValueError: If using all scalar values, you must pass an index”

这可能是一个简单的问题,但我不知道如何做到这一点。假设我有两个变量,如下所示。

1
2
a = 2
b = 3

我想从以下内容构建一个数据帧:

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

这会产生一个错误:

ValueError: If using all scalar values, you must pass an index

我也尝试过:

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

这将给出相同的错误消息。


错误消息指出,如果要传递标量值,则必须传递索引。因此,您不能对列使用标量值——例如,使用列表:

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

或者使用标量值并传递索引:

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


您还可以使用pd.DataFrame.from_records,当您手头已有字典时,这更方便:

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

如果需要,还可以通过以下方式设置索引:

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


你需要先创建一个熊猫系列。第二步是将熊猫系列转换为熊猫数据帧。

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

甚至可以提供列名称。

1
pd.Series(data).to_frame('ColumnName')


您需要提供ITerables作为熊猫数据帧列的值:

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

你可以试着把你的字典包装在列表中

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

pd.DataFrame([my_dict])

1
2
   A  B
0  1  2

也许系列将提供您需要的所有功能:

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

可以将数据帧视为系列的集合,因此您可以:

  • 将多个序列连接到一个数据帧中(如本文所述)

  • 将序列变量添加到现有数据框中(此处为示例)


我对numpy数组也有同样的问题,解决方法是将它们展平:

1
2
3
4
5
6
data = {
    'b': array1.flatten(),
    'a': array2.flatten(),
}

df = pd.DataFrame(data)


如果要转换scalars字典,必须包含索引:

1
2
3
4
5
6
import pandas as pd

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

尽管列表字典不需要索引,但可以将相同的思想扩展到列表字典:

1
2
3
4
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)

当然,对于列表字典,您可以构建不带索引的数据帧:

1
2
planets_df = pd.DataFrame(planets)
print(planets_df)

这是因为数据框架有两个直观的维度——列和行。

您只能使用字典键指定列。

如果只想指定一维数据,请使用序列!


熊猫在工作中有魔力。所有的逻辑都没有了。

错误消息"ValueError: If using all scalar values, you must pass an index"表示必须通过索引。

这并不一定意味着传递一个索引就可以让熊猫做你想做的事情。

当传递索引时,pandas会将字典键视为列名,并将值视为索引中每个值的列应包含的内容。

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

    A   B
1   2   3

传递较大的索引:

1
2
3
4
5
6
7
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

当没有给定索引时,通常由数据帧自动生成索引。然而,熊猫不知道你想要多少行的23。但是你可以更明确地说

1
2
3
4
5
6
7
8
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的。

我建议在创建数据帧时始终将列表字典传递给数据帧构造函数。其他开发人员更容易阅读。熊猫有很多注意事项,不要让其他开发人员为了阅读你的代码而不得不对他们中的所有人都进行专家测试。


这是对@fax回复的注释:输入不必是记录列表-也可以是单个字典:

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

这似乎等同于:

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


你可以试试:

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

来自"orient"参数的文档:如果传递的dict的键应该是结果数据帧的列,则传递"columns"(默认)。否则,如果键应该是行,则传递"index"。


将字典转换为数据帧

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

为列赋予新名称

1
col_dict_df.columns = ['col1', 'col2']

如果你有一本字典,你可以用下面的代码把它变成熊猫数据框:

1
pd.DataFrame({"key": d.keys(),"value": d.values()})


把听写表传给我:

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