【问题标题】:How to compare value of second column with same values of first column in pandas dataframe?如何比较熊猫数据框中第二列的值与第一列的相同值?
【发布时间】:2019-11-19 10:52:19
【问题描述】:

如何针对同一数据框中第一列的所有相同值提取和比较数据框中第二列的值?

我有一个数据框为“df”:

Name         Datetime
Bob          26-04-2018 12:00:00
Claire       26-04-2018 12:00:00
Bob          26-04-2018 12:30:00
Grace        27-04-2018 08:30:00
Bob          27-04-2018 09:30:00

我想在数据框中添加一个新列作为 df['Id'] 这样,对于具有相同名称的用户,如果日期时间值的差异不超过 30 分钟,它们将被分配相同的Id 的值,如果日期时间差大于 30 分钟,则分配不同的 id。

我认为它可以通过迭代循环来实现,但我不知道该怎么做。另外,由于我有一个庞大的数据集,有没有更好的方法来做到这一点?

我预期的数据框输出如下:

Name         Datetime                 Id
Bob          26-04-2018 12:00:00      1
Claire       26-04-2018 12:00:00      2
Bob          26-04-2018 12:10:00      1
Bob          26-04-2018 12:20:00      1
Claire       27-04-2018 08:30:00      3
Bob          27-04-2018 09:30:00      4

任何帮助将不胜感激。 谢谢

【问题讨论】:

  • 您是如何在结果中获得 12:10 和 12:20 的记录的?
  • @ScottBoston 我手动添加它们以明确说明预期结果

标签: python pandas iteration


【解决方案1】:

我会按名称、日期时间对数据框进行排序以识别不同的组,然后按原始数据框顺序为每个组分配一个 Id 值。

代码可以是:

# sort data frame on Name and datetime
df.sort_values(['Name', 'Datetime'], inplace=True)
df1 = df.shift()
# identify new Ids
df.loc[(df1.Name!=df.Name)
       |(df.Datetime-df1.Datetime>pd.Timedelta(minutes=30)), 'tmp'] = 1
del df1   # non longer usefull

# ok, one different tmp value for each group
df['tmp'] = df['tmp'].cumsum().ffill()

# compute Ids in original dataframe orders
ids = pd.DataFrame(df['tmp'].drop_duplicates().sort_index())
ids['Id'] = ids.reset_index(drop=True).index + 1

# and get the expected result
df = df.reset_index().merge(ids, on='tmp').set_index('index').sort_index()\
     .drop(columns='tmp').rename_axis(None)

它按预期给出:

     Name            Datetime  Id
0     Bob 2018-04-26 12:00:00   1
1  Claire 2018-04-26 12:00:00   2
2     Bob 2018-04-26 12:10:00   1
3     Bob 2018-04-26 12:20:00   1
4  Claire 2018-04-27 08:30:00   3
5     Bob 2018-04-27 09:30:00   4

【讨论】:

  • 这很棒。我试图找出不同的方法。
【解决方案2】:

我认为使用groupbygrouperngroup很简单,如下所示:

df['Id'] = df.groupby([pd.Grouper(freq='30T', key='Datetime'), 'Name']).ngroup().add(1)


Out[423]:
     Name            Datetime  Id
0     Bob 2018-04-26 12:00:00   1
1  Claire 2018-04-26 12:00:00   2
2     Bob 2018-04-26 12:10:00   1
3     Bob 2018-04-26 12:20:00   1
4  Claire 2018-04-27 08:30:00   3
5     Bob 2018-04-27 09:30:00   4

【讨论】:

  • 非常感谢。如果我想检查用户“Bob”是否也有一个时间戳为 30 分钟之后的数据点(即 12.30.00 之后),您是否认为可以使用相同的方法,那么这两个组需要合并为一个一个 ID 的单组?
  • 我希望将用户的所有数据点(具有相同的名称)以及其日期时间值具有连续 30 分钟间隔的所有数据点合并到一个具有唯一 ID 的组中。基本上我想为用户创建相同的 ID,这样他们的不活动时间不超过 30 分钟。对于闲置时间超过 30 分钟的用户,将分配另一个 ID。是否可以使用类似的方法?感谢您的帮助!
  • @Jupyter:我不太清楚你对consecutive 30 minute intervalsinactivity more than 30 minute 的描述。这听起来和这个问题很相似,但我不能正面回答。您能否在其上发布一个带有更多解释、示例和所需输出的新问题。评论部分太短,无法提供足够的细节。发布新问题时,您可以链接回此问题以提供更多背景信息。
  • 我已经发布了带有详细信息的问题。 stackoverflow.com/q/56978362/3873482 非常感谢您的帮助!
  • @Jupyter:我回答了你的另一个问题。只需检查一下
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-15
  • 1970-01-01
  • 2016-12-28
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
相关资源
最近更新 更多