使用来自另一列的一些值创建列 - 条件

Create column with some values from another columns - Conditional

我有一列值包含类别示例:New Va,P Va,B...我需要为每个类别和您各自的值创建一个列

       Date  Column1 Total        Type Values
0       NaN      NaN   NaN       Type1    5.1
1       NaN  Column2   Sum       Type1 New Va
2   04/2019        2   NaN       Type1    NaN
3   05/2019        2   NaN       Type1    NaN
4   06/2019        2     2       Type1     14
5   07/2019        4     4       Type1     16
6       NaN      NaN   NaN  Unnamed: 4    NaN
7       NaN  Column2   Sum  Unnamed: 4   P Va
8   04/2019        2   NaN  Unnamed: 4    NaN
9   05/2019        2   NaN  Unnamed: 4    NaN
10  06/2019        2     2  Unnamed: 4     10
11  07/2019        4     4  Unnamed: 4     15
12      NaN      NaN   NaN  Unnamed: 5    NaN
13      NaN  Column2   Sum  Unnamed: 5      B
14  04/2019        2   NaN  Unnamed: 5    NaN
15  05/2019        2   NaN  Unnamed: 5    NaN
16  06/2019        2     2  Unnamed: 5      8
17  07/2019        4     4  Unnamed: 5      7
18      NaN      NaN   NaN       Type2    4.9

考虑到 Date 列中的 NAN 数据值将被删除,预期结果是:

       Date  Column1 Total        Type Values New Va   P Va  B
0       NaN      NaN   NaN       Type1    5.1   
1       NaN  Column2   Sum       Type1      N
2   04/2019        2   NaN       Type1    NaN   0
3   05/2019        2   NaN       Type1    NaN   0
4   06/2019        2     2       Type1     14   14
5   07/2019        4     4       Type1     16   16
6       NaN      NaN   NaN  Unnamed: 4    NaN
7       NaN  Column2   Sum  Unnamed: 4      P
8   04/2019        2   NaN  Unnamed: 4    NaN       0
9   05/2019        2   NaN  Unnamed: 4    NaN       0
10  06/2019        2     2  Unnamed: 4     10       10
11  07/2019        4     4  Unnamed: 4     15       15
12      NaN      NaN   NaN  Unnamed: 5    NaN
13      NaN  Column2   Sum  Unnamed: 5      B            
14  04/2019        2   NaN  Unnamed: 5    NaN              0
15  05/2019        2   NaN  Unnamed: 5    NaN              0
16  06/2019        2     2  Unnamed: 5      8              8
17  07/2019        4     4  Unnamed: 5      7              7
18      NaN      NaN   NaN       Type2    4.9

之后,我将按 Date 中的值进行分组,以使 New Pa、P Va 和 B 的值保持在同一行中。 我正在尝试使用 for 创建新列来标识

 df['New Va'] = np.where(df['Values'].str.contains('New Va'),'N',np.NaN)

但是,所有与P和B不同的行都是NaN,我没有上面例子中的数字

import re  # Not strictly necessary, but it might speed things up for lots of data

pat = re.compile("^[a-zA-Z\s]*$")            # compile is what might speed things up
v = df.Values[df.Column1.notna()].fillna(0) 
a = ~v.str.match(pat).fillna(False)          # mask of things that don't match
keys = pd.unique(v[~a])                      # get unique matches
fill = dict.fromkeys(keys, '')
d = pd.get_dummies(v.mask(a).ffill())[a]
new = d.mul(pd.to_numeric(v[a]), axis=0).where(d == 1, '')[keys]

df.join(new).fillna(fill)

       Date  Column1 Total        Type  Values New Va P Va  B
0       NaN      NaN   NaN       Type1     5.1               
1       NaN  Column2   Sum       Type1  New Va               
2   04/2019        2   NaN       Type1     NaN      0        
3   05/2019        2   NaN       Type1     NaN      0        
4   06/2019        2     2       Type1      14     14        
5   07/2019        4     4       Type1      16     16        
6       NaN      NaN   NaN  Unnamed: 4     NaN               
7       NaN  Column2   Sum  Unnamed: 4    P Va               
8   04/2019        2   NaN  Unnamed: 4     NaN           0   
9   05/2019        2   NaN  Unnamed: 4     NaN           0   
10  06/2019        2     2  Unnamed: 4      10          10   
11  07/2019        4     4  Unnamed: 4      15          15   
12      NaN      NaN   NaN  Unnamed: 5     NaN               
13      NaN  Column2   Sum  Unnamed: 5       B               
14  04/2019        2   NaN  Unnamed: 5     NaN              0
15  05/2019        2   NaN  Unnamed: 5     NaN              0
16  06/2019        2     2  Unnamed: 5       8              8
17  07/2019        4     4  Unnamed: 5       7              7
18      NaN      NaN   NaN       Type2     4.9               

让我们试试:

m = df['Values'].str.contains(r'(?i)^[A-Z\s]+$', na=False)
c, b = list(df.loc[m, 'Values']), m.cumsum()

for _, v in df['Values'].groupby(b):
    if v.iat[0] in c:
        s = v.iloc[1:].fillna(0)
        df.loc[s.index, v.iat[0]] = s

df[c] = df[c].mask(df['Date'].isna()).fillna('')

详情:

使用 str.contains 创建一个布尔掩码,指定 Values 包含 Categories 的条件,如 New VaP VaB:

>>> m
0     False
1      True
2     False
3     False
4     False
5     False
6     False
7      True
8     False
9     False
10    False
11    False
12    False
13     True
14    False
15    False
16    False
17    False
18    False
Name: Values, dtype: bool

识别 Values 列中以类别开头的块:

>>> b

0     0
1     1
2     1
3     1
4     1
5     1
6     1
7     2
8     2
9     2
10    2
11    2
12    2
13    3
14    3
15    3
16    3
17    3
18    3
Name: Values, dtype: int64

在这个元素块上对列 Values 进行分组,对于每个组 add/update 数据框中的类别列,每个块中的类别后面都有值,最后 mask这些新添加的列中的值,其中 DateNaN:

>>> df

       Date  Column1 Total        Type  Values New Va P Va  B
0       NaN      NaN   NaN       Type1     5.1               
1       NaN  Column2   Sum       Type1  New Va               
2   04/2019        2   NaN       Type1     NaN      0        
3   05/2019        2   NaN       Type1     NaN      0        
4   06/2019        2     2       Type1      14     14        
5   07/2019        4     4       Type1      16     16        
6       NaN      NaN   NaN  Unnamed: 4     NaN               
7       NaN  Column2   Sum  Unnamed: 4    P Va               
8   04/2019        2   NaN  Unnamed: 4     NaN           0   
9   05/2019        2   NaN  Unnamed: 4     NaN           0   
10  06/2019        2     2  Unnamed: 4      10          10   
11  07/2019        4     4  Unnamed: 4      15          15   
12      NaN      NaN   NaN  Unnamed: 5     NaN               
13      NaN  Column2   Sum  Unnamed: 5       B               
14  04/2019        2   NaN  Unnamed: 5     NaN              0
15  05/2019        2   NaN  Unnamed: 5     NaN              0
16  06/2019        2     2  Unnamed: 5       8              8
17  07/2019        4     4  Unnamed: 5       7              7
18      NaN      NaN   NaN       Type2     4.9