使用来自另一列的一些值创建列 - 条件
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 Va
、P Va
、B
:
>>> 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
这些新添加的列中的值,其中 Date
是 NaN
:
>>> 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
我有一列值包含类别示例: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 Va
、P Va
、B
:
>>> 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
这些新添加的列中的值,其中 Date
是 NaN
:
>>> 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