对数据框进行条件以创建新的数据框-Python

时间:2018-11-15 18:27:22

标签: python pandas dataframe conditional-statements data-manipulation

我有一个如下数据框。

    id type  value     Date name
0  111    a    100  2018/11   x1
1  112    b    200  2018/12   x2
2  113    a    300  2018/08   x3
3  113    a    200  2018/08   x4
4  114    a    300  2017/12   x4
5  114    a    500  2018/12   x5
6  114    b    500  2018/12   x5

我想基于4个条件创建一个数据框。

  1. 如果id唯一,并输入!= b,则换行并添加case1列
  2. 如果id唯一且类型= b,则在名称唯一的情况下上一行并添加case2列
  3. 如果id不唯一,然后输入!= b,则 汇总具有相同日期的行,求和值,添加case3列
  4. 如果id不唯一并且类型= b,则 汇总具有相同日期的行,对值求和,而忽略类型b的行,添加case4列

新数据框如下所示

    id type  value     Date   case
0  111    a    100  2018/11  case1
1  112    b    200  2018/12  case2
2  113    a    500  2018/08  case3
3  114    a    300  2017/12  case4
4  114    b    500  2018/12  case4

我尝试创建“案例”列作为第一步:

  

对于df.id.unique()中的i:

if 'b' in df.Type:

    df['Case']= 'case 1'

else:

    df['Case']= 'case 2' else:
     

其他:

if 'b' in df.Type:

    df['Case']= 'case 3'

else:

    df['Case']= 'case 4'

对熊猫操作不熟悉,因此建议会受到赞赏

1 个答案:

答案 0 :(得分:0)

您可以使用此:

# groupby and add group sizes
df['id_count'] = df.groupby('id')['id'].transform('size')

# conditions for np.select
conditions = [
    (df['id_count'].eq(1) & df['type'].ne('b')),
    (df['id_count'].eq(1) & df['type'].eq('b')),
    (df['id_count'].ne(1) & df['type'].ne('b')),
    (df['id_count'].ne(1) & df['type'].eq('b'))]
# choices for np.select
choices = ['case1', 'case2', 'case3', 'case4']
# Add case column
df['case'] = np.select(conditions, choices, default=None)

# next grouping
grouping = ['id', 'type', 'Date', 'case']
# replace value column
df['value'] = df.groupby(grouping)['value'].transform('sum')

# drop duplicate rows
df = df.drop_duplicates(subset=grouping, keep='first')
# remove extra columns
df = df.drop(['name', 'id_count'], axis='columns')

一步一步

首先,您可以在id列中创建一个groupby,如下所示:

gb = df.groupby('id')

然后,您可以使用它来计算id发生的次数:

df['id_count'] = gb['id'].transform('size')

df现在看起来像这样:

    id type  value     Date name  id_count
0  111    a    100  2018/11   x1         1
1  112    b    200  2018/12   x2         1
2  113    a    300  2018/08   x3         2
3  113    a    200  2018/08   x4         2
4  114    a    300  2017/12   x4         3
5  114    a    500  2018/12   x5         3
6  114    b    500  2018/12   x5         3

现在,您可以使用np.select来设置条件:

conditions = [
    (df['id_count'].eq(1) & df['type'].ne('b')),
    (df['id_count'].eq(1) & df['type'].eq('b')),
    (df['id_count'].ne(1) & df['type'].ne('b')),
    (df['id_count'].ne(1) & df['type'].eq('b'))]
choices = ['case1', 'case2', 'case3', 'case4']
df['case'] = np.select(conditions, choices, default=None)

结果:

    id type  value     Date name  id_count   case
0  111    a    100  2018/11   x1         1  case1
1  112    b    200  2018/12   x2         1  case2
2  113    a    300  2018/08   x3         2  case3
3  113    a    200  2018/08   x4         2  case3
4  114    a    300  2017/12   x4         3  case3
5  114    a    500  2018/12   x5         3  case3
6  114    b    500  2018/12   x5         3  case4

使用grouping(列的列表)创建另一个组;然后在这些组中的sum value列中替换value列。

grouping = ['id', 'type', 'Date', 'case']
df['value'] = df.groupby(grouping)['value'].transform('sum')

结果:

    id type  value     Date name  id_count   case
0  111    a    100  2018/11   x1         1  case1
1  112    b    200  2018/12   x2         1  case2
2  113    a    500  2018/08   x3         2  case3
3  113    a    500  2018/08   x4         2  case3
4  114    a    300  2017/12   x4         3  case3
5  114    a    500  2018/12   x5         3  case3
6  114    b    500  2018/12   x5         3  case4

最后,drop-duplicates使用之前的grouping列表:

df = df.drop_duplicates(subset=grouping, keep='first')

给予:

    id type  value     Date name  id_count   case
0  111    a    100  2018/11   x1         1  case1
1  112    b    200  2018/12   x2         1  case2
2  113    a    500  2018/08   x3         2  case3
4  114    a    300  2017/12   x4         3  case3
6  114    b    500  2018/12   x5         3  case4

您可以使用drop删除多余的列:

df = df.drop(['name', 'id_count'], axis='columns')