条件转换直到上一个类别

时间:2017-12-01 12:54:48

标签: python pandas

我想提起其他人先前提出的问题: Pandas and Python Dataframes and Conditional Shift Function 有人询问如何获得大熊猫中同一类型的前一辆车的销售日期,用户要求提供状态转换功能。答案虽然是一个汽车和一个班次,这解决了问题。 现在我想计算,例如不同(例如按字典顺序)类型的汽车的销售日期。因此,转移到条件(汽车类型改变)的条件转换功能将解决问题。如何做到这一点?谢谢!

编辑:

An example from my part, my dataframe is:
  A  B     Previous   MyPrevious
0 0  1.5   nan        nan
1 0  2     1.5        nan
2 0  2.5   2          nan
3 1  3.7   nan        2.5
4 1  4     3.7        2.5
5 2  4.2   nan        4

它已经按A和B排序。前一位提问者想知道“B的前一个值是什么,其中A是同一类型”。因此,您可以在第0行中看到没有前一行因此为nan,在第1行中前一行也具有A = 0 =>上一个= 1.5,依此类推。我现在想要“B列的前一个值,其中A小于1”。对于A = 0的所有行的含义,我们没有任何行,其中A是-1,因此是nan。对于A = 1的所有行,我们取A = 0的最后一行,这里B是2.5。我希望这可以解释它。

1 个答案:

答案 0 :(得分:2)

您仍然可以使用groupbyshift,但方式略有不同:

df = pd.DataFrame({'A': [0,0,0,1,1,2], 'B':[1.5,2,2.5,3.7,4,4.2]})
grouped = df.groupby('A', as_index=False).last().shift().B
grouped = pd.DataFrame(grouped)
pd.merge(df, grouped, left_on='A', right_index=True)

输出:

   A  B_x  B_y
0  0  1.5  NaN
1  0  2.0  NaN
2  0  2.5  NaN
3  1  3.7  2.5
4  1  4.0  2.5
5  2  4.2  4.0

注意:这确实假设A包含从0到max(df.A)

的所有连续数字

编辑:差异并将B的第三个值更改为1

df = pd.DataFrame({'A': [0, 0, 0, 1, 1, 2], 'B': [1.5, 2, 2.5, 1, 4, 4.2]})
grouped = df.groupby('A', as_index=False).min().shift().B
grouped = pd.DataFrame(grouped)
merged = pd.merge(df, grouped, left_on='A', right_index=True)
print(np.abs(merged.B_x - merged.B_y))

输出:

0    NaN
1    NaN
2    NaN
3    0.5
4    2.5
5    3.2
dtype: float64

编辑2:

这花了我一段时间,但我认为它现在有效。不要认为它是最佳解决方案,但它有效;)

def f(x):
    if x.B_y != x.B_y:  # Check if value is NaN
        return np.nan
    return x.B_x - min(x.B_y, key=lambda v: abs(v - x.B_x))

df = pd.DataFrame({'A': [0, 0, 0, 1, 1, 2], 'B': [1.5, 2, 2.5, 3, 4, 4.2]})
a = pd.DataFrame(df.groupby('A').B.apply(list).shift())
result = pd.merge(df, a, left_on='A', right_index=True).apply(f, axis=1)
print(result)

输出:

0    NaN
1    NaN
2    NaN
3    0.5
4    1.5
5    0.2
dtype: float64

现在在a中存储了前一组的列表,然后可以在索引的数据框中合并这些列表。然后,函数f(x)应用于查找x.B_xx.B_y(列表)值之间的最小距离的所有行。