我正在使用Pandas,我有一个主要的Assy、Sub Assy I、Sub Assy II和Sub Assy III的大部分列表,每行只有一个"Assy“列可以用一个字符串填充。其目的是将各部件的排列转换为编号的system.The,下表显示了预期的结果
Main Assy Sub Assy I Sub Assy II Sub Assy III Level I Level II Level III Level IV
asd 1 0 0 0
fgd 1 1 0 0
sdd 1 1 1 0
dsd 1 1 2 0
fhg 1 1 3 0
tdc 1 1 3 1
dyx 1 1 3 2
dsg 1 1 3 3
dfg 1 2 0 0
cvf 1 2 1 0
ngs 1 2 2 0
vbn 1 2 3 0
dsd 1 2 3 1
vcd 1 2 3 2
cbn 1 2 3 3
ged 2 0 0 0
dfs 2 1 0 0
aef 2 1 1 0我的计划是对“级别”-columns中的行进行累加,只要在较高级别上没有变化。因此,当在较高级别上发生更改时,较低级别上选定的单元格需要返回到零。有没有变化,它保持相同的号码。我尝试了以下几点:
df[lambda df: df.columns[0:4]] = df[lambda df: df.columns[0:4]].isna()
for index in range(0,4):
mask = ((df.iloc[:,index] == False))
print(mask)
df.iloc[:,(index+4)] = mask.groupby((~mask).cumsum()).cumsum().astype(int)因此,我通过搜索缺少的值来检查单元格是否被填充。由于数据帧大,我不想对每一行都使用有很多条件的循环。我只在列上使用这个FOR-循环,并试图通过创建一个掩码来累积,该掩码显示从FALSE到TRUE的更改。
的实际结果是:
Main Assy Sub Assy I Sub Assy II Sub Assy III Level I Level II Level III Level IV
asd 1 0 0 0
fgd 0 1 0 0
sdd 0 0 1 0
dsd 0 0 2 0
fhg 0 0 3 0
tdc 0 0 0 1
dyx 0 0 0 2
dsg 0 0 0 3
dfg 0 2 0 0
cvf 0 0 1 0
ngs 0 0 2 0
vbn 0 0 3 0
dsd 0 0 0 1
vcd 0 0 0 2
cbn 0 0 0 3
ged 2 0 0 0
dfs 0 1 0 0
aef 0 0 1 0在不使用循环的情况下设置上述条件计数的正确方法是什么?
发布于 2020-10-29 18:53:56
钥匙
要在每一行上应用的输出的变化可以完全由当前“级别”和前一个级别决定。这里的“级别”是指列的索引号,该列有一个非零项。
换句话说,保留上一行级别的状态变量足以正确填充当前行。
代码
# the working dataset
df2 = df.iloc[:, :4].reset_index(drop=True) # make a copy
df2.columns = range(4) # rename columns to (0,1,2,3) for convenience
# output container
arr = np.zeros(df2.shape, dtype=int)
# state variable: level of the last row
last_lv = 0
for idx, row in df2.iterrows():
# get current indentation level
lv = row.first_valid_index()
if idx > 0:
# case 1: same or decreased level
if lv <= last_lv:
# keep previous levels except current level
arr[idx, :lv] = arr[idx-1, :lv]
# current level++
arr[idx, lv] = arr[idx-1, lv] + 1
# case 2: increased level
elif lv > last_lv:
# keep previous levels
arr[idx, :last_lv+1] = arr[idx - 1, :last_lv+1]
# start counting the new levels
arr[idx, last_lv+1:lv+1] = 1
# the first row
else:
arr[0, 0] = 1
# update state variable for next use
last_lv = lv
# append result to dataframe
df[["Level I", "Level II", "Level III", "Level IV"]] = arr结果
print(df[["Level I", "Level II", "Level III", "Level IV"]])
Level I Level II Level III Level IV
0 1 0 0 0
1 1 1 0 0
2 1 1 1 0
3 1 1 2 0
4 1 1 3 0
5 1 1 3 1
6 1 1 3 2
7 1 1 3 3
8 1 2 0 0
9 1 2 1 0
10 1 2 2 0
11 1 2 3 0
12 1 2 3 1
13 1 2 3 2
14 1 2 3 3
15 2 0 0 0
16 2 1 0 0
17 2 1 1 0备注
https://stackoverflow.com/questions/64595790
复制相似问题