我提前为提出这样一个基本问题而道歉,但我很难过。
这是一个非常简单的虚拟例子。我在Pandas中遇到了一些与日期匹配的问题,我无法弄明白为什么。
df = pd.DataFrame([[1,'2016-01-01'],
[2,'2016-01-01'],
[3,'2016-01-02'],
[4,'2016-01-03']],
columns=['ID', 'Date'])
df['Date'] = df['Date'].astype('datetime64')
说我想匹配上面df中的第1行
我事先知道我想要匹配ID 1
而且我也知道我想要的日期,事实上,我将直接从df的第1行提取该日期,以使其具有防弹性。
some_id = 1
some_date = df.iloc[1:2]['Date'] # gives 2016-01-01
那么为什么这一行不能让我回到第1行?
df[(df['ID']==some_id) & (df['Date'] == some_date)]
相反,我得到了
ValueError: Series lengths must match to compare
答案 0 :(得分:9)
你说:
some_date = df.iloc[1:2]['Date'] # gives 2016-01-01
但是不是它给出的东西。它为一个系列提供了一个元素,而不仅仅是一个值 - 当你使用[1:2]
作为切片时,你没有得到一个元素,而是一个带有一个元素的容器:
>>> some_date
1 2016-01-01
Name: Date, dtype: datetime64[ns]
相反,做
>>> some_date = df.iloc[1]['Date']
>>> some_date
Timestamp('2016-01-01 00:00:00')
之后
>>> df[(df['ID']==some_id) & (df['Date'] == some_date)]
ID Date
0 1 2016-01-01
(请注意,如果要查找大量some_id
和some_date
值,则效率模式会更高效,但这是一个单独的问题。)
答案 1 :(得分:1)
如DSM所述,some_date是一个系列,而不是一个值。当您使用布尔掩码,并检查列的值是否等于某个变量时,我们必须确保该变量是值,而不是容器。 DSM提到了一种解决问题的可能方法,还有另一种解决问题的方法。
df[(df['ID']==some_id) & (df['Date'] == some_date.values[0])]
我们刚刚用some_date.values [0]替换了some_date。 some_date.values返回一个包含一个元素的数组。我们对容器(而不是容器)中的值感兴趣,因此我们将其索引为[0]以获取该值。