我有一个pandas数据帧,其中一列包含1-D numpy数组,另一列包含标量数据,例如:
df =
A B
0 x [0, 1, 2]
1 y [0, 1, 2]
2 z [0, 1, 2]
我希望在A=='x'
的行中得到B所以我尝试df[df.A == 'x'].B.values
给出了输出:
array([array([0, 1, 2])], dtype=object)
输出周围有一个额外的array([])
。我知道Pandas将它视为一个对象,而不仅仅是数据,我可以使用df[df.A == 'x'].B.values[0]
来访问数组。在标量数据的情况下,我可以使用语法df[df.A == 'x'].B
,它比我必须使用的df[df.A == 'x'].B.values[0]
更清晰。
我的问题是:是否有更好/更清洁/更短的方式以我放入的格式访问数据?或者这只是我必须忍受的东西?
答案 0 :(得分:2)
不同之处不在于数组是一个对象,而是您指定的查询可能返回多个对象(因此外部数组())。如果您确信查询只返回一个对象,那么您可以使用@Wen的解决方案来使用.item()
:
In [1]: import pandas as pd
In [2]: df = pd.DataFrame([
...: dict(A='x', B=[0,1,2]),
...: dict(A='y', B=[0,1,2]),
...: dict(A='z', B=[0,1,2]),
...: ])
In [3]: df[df.A == 'x'].B.item()
Out[3]: [0, 1, 2]
但根据查询的类型,您至少应该考虑检查结果以确保:
In [4]: df = pd.DataFrame([
...: dict(A='x', B=[0,1,2]),
...: dict(A='y', B=[0,1,2]),
...: dict(A='z', B=[0,1,2]),
...: dict(A='x', B=[3,3,3]),
...: ])
In [5]: df[df.A == 'x'].B.item()
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-8-e0ad528e719e> in <module>()
----> 1 df[df.A == 'x'].B.item()
...
ValueError: can only convert an array of size 1 to a Python scalar
In [6]: df[df.A == 'x'].B.values
Out[6]: array([[0, 1, 2], [3, 3, 3]], dtype=object)
答案 1 :(得分:0)
您可以使用squeeze
方法。如果应用过滤器后的结果只包含一行,则会返回行的内容,因为它会将其转换为低一维。
In[103]: df = pd.DataFrame([['x', [1, 2, 3]], ['y', [1, 2, 3]], ['y', [1, 2, 3]]], index=[0, 1, 2], columns=['A', 'B'])
In[104]: df
Out[104]:
A B
0 x [1, 2, 3]
1 y [1, 2, 3]
2 y [1, 2, 3]
In[105]: df[df.A == 'x'].B.squeeze()
Out[105]: [1, 2, 3]
In[106]: df[df.A == 'y'].B.squeeze()
Out[106]:
1 [1, 2, 3]
2 [1, 2, 3]
Name: B, dtype: object
答案 2 :(得分:0)
使用loc
时,您将获得不同的对象,具体取决于您传递的索引器。在您的示例中:
df.loc[df.A == 'x', 'B']
你传递df.A == 'x'
,它返回pd.Series
个布尔值。由于这是一个类似输入的数组,因此可以保证获得扩展索引维度的输出。
现在因为第二个索引器是标量'B'
,所以不会扩展列维度。因此输出的是pd.Series
对象,其索引由布尔系列df.A == 'x'
为True
且名称为'B'
0 [1, 2, 3]
Name: B, dtype: object
简而言之这与列'B'
中的数组无关
选项1
从df.A == 'x'
df.loc[df.A.eq('x').idxmax(), 'B']
[1, 2, 3]
选项2
设置索引
df.set_index('A').B.loc['x']
[1, 2, 3]
选项3
棘手的词典
我对这个选项并不是很认真。我只是觉得很酷。正如评论中所提到的,有许多事情可能会出错。
dict(df.values)['x']
[1, 2, 3]
然而,稍作修改,我们可以提高稳健性。
dict(df[['A', 'B']].values)['x']