【问题标题】:Conditional fill dataframe pandas条件填充数据框熊猫
【发布时间】:2016-12-11 13:48:54
【问题描述】:

我对 pandas 还很陌生,所以请多多包涵。我有一个包含交互数据的数据框(交互的开始时间、交互的结束时间、进行交互的 userA 和 userB):

开始、结束、用户A、用户B。

现在我想将此数据转换为以下格式(从 0 到 x 的时间,一个用户的 userId,如果有交互,则为布尔值 yes 或 no)。

时间、用户 ID、交互。

我看到了一些关于使用 np.where 的条件数据帧的帖子,但我还不确定如何将它们结合在一起。很抱歉没有提供代码示例。

示例: (输入):

begin, end, userA, userB

130,     300, 1, 2

(输出):

time, user, interaction

...

130, 1, yes

130, 2, yes

131, 1, yes

131, 2, yes

...

300, 1, yes

300, 2, yes

301, 1, no

301, 2, no

有人能指出我正确的方向吗,比如:我应该研究的方法?

【问题讨论】:

  • 您是否在真实数据集中使用 130、131、..、300 等整数作为开始时间和结束时间?
  • 是的,我没有日期/日期时间类型。
  • 你是如何在想要的数据集中得到 301 的?是预定义的吗?
  • 所需集合中的时间是预定义的范围(0 到 1000)。所需数据应在交互仍在发生的每个 t 处列出 yes(在本例中从 t=130 到 t=300)。

标签: python pandas dataframe conditional data-science


【解决方案1】:

假设您有以下源 DF:

In [134]: df
Out[134]:
   begin  end  userA  userB
0    130  134      1      2
1    201  203      5      1
2    333  334      2      5

我们可以做到以下几点:

time_range = np.arange(0, 1001)

dfs = []
for u in df[['userA','userB']].stack().unique():
    dfs.append(pd.DataFrame({'time':time_range,
                             'user':[u] * len(time_range),
                             'interaction': ['no'] * len(time_range)}))
rep = pd.concat(dfs, ignore_index=True)

for i,r in df.iterrows():
    qry = 'user in {} and {} <= time <= {}'.format([r.userA, r.userB], r.begin, r.end)
    print('Query: [{}]'.format(qry))
    rep.ix[rep.eval(qry), 'interaction'] = 'yes'

输出:

Query: [user in [1, 2] and 130 <= time <= 134]
Query: [user in [5, 1] and 201 <= time <= 203]
Query: [user in [2, 5] and 333 <= time <= 334]

检查:

In [133]: rep[rep.interaction == 'yes']
Out[133]:
     interaction  time  user
130          yes   130     1
131          yes   131     1
132          yes   132     1
133          yes   133     1
134          yes   134     1
201          yes   201     1
202          yes   202     1
203          yes   203     1
1131         yes   130     2
1132         yes   131     2
1133         yes   132     2
1134         yes   133     2
1135         yes   134     2
1334         yes   333     2
1335         yes   334     2
2203         yes   201     5
2204         yes   202     5
2205         yes   203     5
2335         yes   333     5
2336         yes   334     5

【讨论】:

  • 这正是我想要的。非常感谢!你用 stack().unique() 方法做了一件好事。
  • @Bram,很高兴我能帮上忙 :)
猜你喜欢
  • 1970-01-01
  • 2018-06-20
  • 2019-05-04
  • 1970-01-01
  • 2020-01-19
  • 2020-03-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多