我想提起其他人先前提出的问题: 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。我希望这可以解释它。
答案 0 :(得分:2)
您仍然可以使用groupby
和shift
,但方式略有不同:
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_x
与x.B_y
(列表)值之间的最小距离的所有行。