python - Pandas 操纵: Non-distinct groups

标签 python python-2.7 pandas

我有一个数据框:

Time    c_1     c_2   
 t1      x       1
 t2      x       2
 t3      y       1
 t4      y       2
 t5      1       x
 t6      2       x
 t7      1       y
 t8      2       y

我需要在不循环的情况下形成 2 列,这样:

  • new_1:c_1.value 出现在 c_2 中的下一个最早时间(例如,对于 t1,new_1 = t5,因为 c_1 值为 'x',下一次 'x' 出现在 c_2 中是在 t5)
  • new_2:c_2.value 下一次出现在 c_1 中的最早时间(例如,对于 t1,new_1 = t5,因为 c_2 值为 '1',下一次 '1' 出现在 c_1 中是在 t3)

所以对于上面的输入,输出应该是:

Time    c_1     c_2    new_1     new_2
 t1      x       1       t5        t5
 t2      x       2       t5        t6
 t3      y       1       t7        t5            
 t4      y       2       t7        t6      
 t5      1       x       NaT       NaT
 t6      2       x       NaT       NaT
 t7      1       y       NaT       NaT
 t8      2       y       NaT       NaT

你会如何处理这个问题?

最佳答案

这是一个使用 apply() 和 lambda 函数从原始 DataFrame 中为每一行选择正确数据的解决方案。

import pandas as pd

data = {'Time': pd.date_range('1/1/2000', periods=16, freq='D'),
        'c_1': ['x', 'x', 'y', 'y', '1', '2', '1', '2']*2,
        'c_2': ['1', '2', '1', '2', 'x', 'x', 'y', 'y']*2 }

df = pd.DataFrame(data)    
df['new_1'] = df.apply(lambda r: (df.Time[(df.Time>r.Time) & (df.c_2 == r.c_1)].head(1).reset_index(drop=True)), axis=1)
df['new_2'] = df.apply(lambda r: (df.Time[(df.Time>r.Time) & (df.c_1 == r.c_2)].head(1).reset_index(drop=True)), axis=1)
print(df)

输出是:

         Time c_1 c_2      new_1      new_2
0  2000-01-01   x   1 2000-01-05 2000-01-05
1  2000-01-02   x   2 2000-01-05 2000-01-06
2  2000-01-03   y   1 2000-01-07 2000-01-05
3  2000-01-04   y   2 2000-01-07 2000-01-06
4  2000-01-05   1   x 2000-01-09 2000-01-09
5  2000-01-06   2   x 2000-01-10 2000-01-09
6  2000-01-07   1   y 2000-01-09 2000-01-11
7  2000-01-08   2   y 2000-01-10 2000-01-11
8  2000-01-09   x   1 2000-01-13 2000-01-13
9  2000-01-10   x   2 2000-01-13 2000-01-14
10 2000-01-11   y   1 2000-01-15 2000-01-13
11 2000-01-12   y   2 2000-01-15 2000-01-14
12 2000-01-13   1   x        NaT        NaT
13 2000-01-14   2   x        NaT        NaT
14 2000-01-15   1   y        NaT        NaT
15 2000-01-16   2   y        NaT        NaT

apply 是通过 axis=1 完成的,所以它一次迭代一行。 lambda 函数仅选择数据帧中出现在当前行之后且列中具有正确值的行。可能有多个行符合这些条件。 head(1) 选择第一个匹配项,reset_index(drop=True) 确保返回的每个 Series 具有相同的索引 (0),以便 apply () 将它们全部从返回值中放到一个列中。

关于python - Pandas 操纵: Non-distinct groups,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43158177/

相关文章:

python - Raspberry pi3 Mysql Python 错误

python - 具有自动标签功能的标签堆叠条

Python __super黑魔法失败了

python - 在 Pandas 中用 NaN 替换多列中的多个字符串和数字

python - 如何使用 Bokeh 动态隐藏字形和图例项

python - 如何在 Django 1.6 中使用 time.strftime

python - 网页抓取失败 - 美丽的汤

python - 我应该使用哪种授权授予类型?

python - 使用 mysql-server 设置 django 时出现异常

python - 将 Pandas 函数应用于列以创建多个新列?