首页 > 解决方案 > Python 随条件旋转

问题描述

假设我有以下数据框:

班级号 姓名 结果_Str Result_Num
123 助教 克拉克
456 助教 鲍里斯
456 托尼 >87
123 山姆 <45
456 安娜 89
456 西奥 67

我希望能够转向这样的东西,其中包含 >,< 的值被放入类似的列中,就像Result_Num的情况一样:

|ClassID| TA  |Anna|Tony|Sam|Theo|
|-------|-----|----|----|---|----|
|123    |Clark|    |    |<45|    |
|456    |Boris|89  |>87 |   |67  |

我知道pandas的 df.pivot 允许我们这样做

df.pivot(index="ClassID", columns="Name",values="Result_Str")
df.pivot(index="ClassID", columns="Name",values="Result_Num")

但是可以根据是否定义/不等于“”来使值有条件Result_NumResult_Str

谢谢,

标签: pythonpandaspivot

解决方案


您必须在枢轴之前准备好数据框。首先,(1)创建一个布尔掩码来查找不在右列中的值并移动它们。然后,(2A)将您的数据框拆分为 2 个子数据框:一个用于Result_Str列,另一个用于Result_Num列,(2B)对它们进行旋转。ClassID最后,(3)在列上合并您的 2 个数据框:

# (1)
m = df['Result_Str'].str[0].isin(['<', '>'])
df.loc[m, 'Result_Num'], df.loc[m, 'Result_Str'] = df.loc[m, 'Result_Str'], np.nan

# (2A)
df1 = df.loc[df['Result_Str'].notna()].drop(columns='Result_Num')
df2 = df.loc[df['Result_Num'].notna()].drop(columns='Result_Str')

# (2B)
df1 = df1.pivot(index='ClassID', columns='Name', values='Result_Str')
df2 = df2.pivot(index='ClassID', columns='Name', values='Result_Num')

# (3)
out = pd.merge(df1, df2, on='ClassID').rename_axis(columns=None).reset_index()

输出结果:

>>> out
   ClassID     TA  Anna  Sam  Theo Tony
0      123  Clark   NaN  <45   NaN  NaN
1      456  Boris  89.0  NaN  67.0  >87

推荐阅读