【问题标题】:Pandas - Returning coordinates and value when conditional values are metPandas - 满足条件值时返回坐标和值
【发布时间】:2017-03-23 09:54:43
【问题描述】:

我正在使用 pandas 和 python 2.7.13,我一直在尝试通过 pandas 导入一个 excel 文件,并使用指定条件比较来自两个单独数据帧的数据,以查找 DF2 中的值何时落在 DF1 中的两个时间值之间,以及如果满足条件,则将一个值从 DF1 返回到 DF2。

数据集由 DF2 组成,这是一个包含 DateX(MM/DD/YYYY HH:MM)的大型记录数据库,而 DF1 是人员配备时间的导出,其格式为开始时间和结束时间,两者的格式都与人员相同名称。我们使用第 3 方系统进行人员配置,它没有连接到我们的数据库和我正在生成的报告,我们需要查看特定员工如何影响绩效。

示例数据:

DF1
Employee:    Start Time:    End Time:
John Smith  1/1/2017 06:30 1/1/2017 18:30
Jane Smith  1/1/2017 06:30 1/1/2017 18:30
Tommy Boy  1/2/2017 06:30  1/2/2017 15:00

DF2
DateX:
1/1/2017 12:16
1/1/2017 06:43
1/2/2017 19:32

我对 python 有一些经验,但这是我第一次使用 Pandas 和 numpy,我的经验纯粹是基于我尝试过的项目的项目。我当前的代码如下:

import pandas as pd
file = 'sample set.xlsx'

xl = pd.ExcelFile(file)

df1 = xl.parse('Sheet1')
df2 = xl.parse('Sheet2')

for i in df2['DateX']:
    if any(i >= df1['Start Time.1']) and any(i <= df1['End Time.1']):
        print i

我目前只是尝试打印 i 以确保我正在提取正确的数字,因为我使用有限的数据集作为测试场。我遇到两个问题。可以有来自 DF1 的多个工作人员使用来自 DF2 的 DateX,但如果甚至有 1 个匹配项,这将停止。

另一项是我接受了这一点,并尝试弄清楚如何让它打印出来自 df1['Employee'] 的匹配项,但我的努力只产生了整个员工列。这是我学习的一个步骤,试图让它在 DF2 上的 datex 旁边添加匹配的名称。

我仍在继续尝试和阅读文档,如果我自己解决问题,我会更新/关闭。谢谢。

【问题讨论】:

  • 挖掘我已经得到了进一步的调整,以便开始限制我的数据。我首先创建了一个包含所有 dateX 的列表,称为数据时间。然后我做了'for i in datetimes: print df1[(df1['Start Time.1'] i)]' 让我对列表进行排序,所以你只查看它满足的适用数据。我现在可以看到哪些员工姓名,但我需要将该员工姓名应用于与 dateX 匹配的 df2。
  • 对于df2 中的每个DateX 值,您是否希望df1 中具有DateX 值介于Start TimeEnd Time 之间的所有员工记录?你能打印出正确答案的样子吗?
  • 基于上述示例数据的正确答案将在 DF2 DateX: 1/1/2017 12:16 | John Smith | Jane Smith 1/1/2017 | John Smith | Jane Smith 1/2/2017 NAN 中或只是空白。我现在对其进行排序并打印出 DateX 和所有匹配的员工姓名,但不知道如何执行 .join 或附加到 DF2 以使这些匹配项出现在正确 DateX 旁边的列中
  • 您的问题听起来与我回答的here 非常相似。您想找到与您的时间戳相对应的索引范围,然后对这些范围内的值执行您需要的任何聚合。

标签: python pandas numpy


【解决方案1】:

我的回答与@Jay 的类似,但每次都会返回一份员工名单。不幸的是,Pandas 不支持 SQL 等条件连接。有一个新函数merge_asof,但它只为每一行返回一个值,这对你不起作用。

以下将起作用,但速度很慢。

dfs = []

for i, row in df1.iterrows():
    criteria = (row['Start Time'] <= df2['DateX']) & (df2['DateX'] <= row['End Time'])
    if not criteria.all():
        dfs.append(df2[criteria].assign(Employee=row['Employee']))

df2_all = pd.concat(dfs)
df2_agg = df2_all.groupby('DateX').agg(lambda x: ' | '.join(x.tolist()))
df2_final = df2_agg.reindex(df2.DateX)

                                     Employee
DateX                                        
2017-01-01 06:43:00  [John Smith, Jane Smith]
2017-01-01 12:16:00  [John Smith, Jane Smith]
2017-01-02 19:32:00                       NaN

【讨论】:

  • Ted,您的答案直接开箱即用,并在 df2_all 阶段产生与 Jays 相同的答案。在您当前的最终状态下,我遇到了一个问题,如果我将其导出到 excel 中以与我的其余仓库数据结合,它在一列中有 u'[John Smith, Jane Smith]'。在 df2_all 它看起来删除了 unicode 标记。我会尝试自己解决,但是如果有 2 个名称从 1 列结束到与所述 Datex 关联的 2 列中,我将如何移动。
  • @A.McMaster 您可以将所有值放入一个字符串而不是列表。请参阅上面的更改。我使用管道字符来分隔,但你可以使用任何你想要的。
  • 特德,谢谢!我将继续尝试并学习如何更多地使用 pandas,但这有助于我完成一个工作项目,而不会浪费大量时间来 100% 了解学习曲线。有了这个,我能够在 excel 中对其进行操作以适合我的数据集,重新输入并允许我执行我的相关性分析。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-06
  • 1970-01-01
  • 2021-09-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多