Pandas合并和筛选

6

我使用了merge函数来创建两个查询之间的数据框,现在我想要在数据框中对一个列应用筛选器,但是我无法使其生效。我试图添加筛选条件:日期为空或空白。

    ##reading data from sql
    package = pd.read_sql(sql,con)
    component = pd.read_sql(sqla,con)

    ##doing the left join
    test2 = pd.merge(package,component, on = ['identifier','date'], how='left')

    ##shrinking the dataframe   
    test3 = test2[['identifier_x']].copy()

我尝试过以下操作,但无法使其工作。出现“date_y未定义”的错误。我也尝试了只使用date,因为当我合并我的数据框时,相似的列会被标记为xy

 test2 = pd.merge(package,component, on = ['identifier','date'], how='left'), component.query(date_y == '')

现在正在尝试:

test2 = pd.merge(package,component, on = ['identifier','date'], how='left')
test2.query('date_y == \'\'')

并且
test2 = pd.merge(package,component, on = ['identifier','date'], how='left')
test2[test2.date_y == '']

也尝试过:

test2 = pd.merge(package,component, on = ['identifier','date'], how='left')
test2 = test2.date_y == ''

样例数据:

+------------+------------+------------+------------+
|   date_x   | identifier |   date_y   | identifier |
+------------+------------+------------+------------+
| 13/03/2019 | 3582191409 | 13/03/2019 | 3582191410 |
| 13/03/2019 | 3582191289 | 13/03/2019 | 3582191290 |
| 13/03/2019 | 3582190137 | 13/03/2019 | 3582190138 |
| 13/03/2019 | 3582185931 | 13/03/2019 | 3582185930 |
| 13/03/2019 | 3582184503 |            | 3582184502 |
| 13/03/2019 | 3582195631 |            | 3582195632 |
| 13/03/2019 | 3582191374 |            | 3582191373 |
| 13/03/2019 | 3582185917 |            | 3582185916 |
| 13/03/2019 | 3582185863 |            | 3582185862 |
+------------+------------+------------+------------+

我正在尝试过滤日期,其中 y = 空白。


你把括号放在正确的位置了吗?仅凭肉眼看,似乎错了。 - Berenger
@Berenger,括号看起来对我来说没问题。 - excelguy
1
在你的最终 test2 中。它目前设置为创建一个元组,其中包括两个项目:第一个是您合并的 DataFrame,第二个是从 SQL 读取时定义的 component 的过滤版本。如果您想使用 pd.query 过滤合并的 DataFrame,则需要在新行上使用以下内容:test2.query('date_y == \'\'')。请注意,使用 pd.query 时,整个查询都需要在反引号中。同样,您可以使用:test2[test2.date_y == ''] - Berenger
2
如果您发布组件和包的一些样本数据,那么这可能会很有用。 - Berenger
@excelguy,您能否发布一个包和组件的简短示例,以便我们可以重现您的错误? - vlemaistre
显示剩余14条评论
2个回答

7

您可能在阅读空白内容。首先,请确保date_x和date_y是时间戳,并将所有空白替换为np.nan:

test2['date_y']=test2['date_y'].replace(' ',np.nan)
test2['date_x']=pd.to_datetime(test2['date_x'])
test2['date_y']=pd.to_datetime(test2['date_y'])
test2_filtered=test2.loc[test2['date_y'].isnull()]

谢谢Nev,这个方法有效。你能解释一下你做了什么吗? - excelguy
当然,我所做的是重新创建您发布的数据框,确保“date_y”字段中的每个空白都填充了一个空格(“ ”字符)。然后,我用null / nan(或什么也没有)替换了空白字符。(第1行)然后在第2和第3行中,我使用pd.to_datetime将“date_x”和“date_y”字段中包含的数据类型转换为日期戳。最后,我只是过滤掉了空值(即不包含任何内容的字段)。希望这可以帮助您! - Nev1111

2
你正在尝试过滤字符串,但它不是一个字符串 - 它是一个空的datetime.date对象。你需要通过非空日期对象进行筛选。
你可以创建一个第二个数据框作为字符串类型,然后进行检查:
"最初的回答"
str_test2 = test2.astype(str)
filtered_test2 = test2[str_test2['date_y'] != '']

在这里查看更多可能的解决方案

原始答案翻译成“最初的回答”。


不知何故,它没有过滤,但代码运行正常。但是当我输出filtered_test2时,date_y中仍然有空白。 - excelguy
奇怪。我链接的帖子中的其他答案也没有帮助吗? - Zionsof
太好了! :) 很高兴我能帮到你。 - Zionsof

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接