我有一个熊猫数据框df:
import pandas as pd
import numpy as np
data = {'A':[250,100,400,np.nan,300]}
df = pd.DataFrame(data)
print(df)
A
0 250.0
1 100.0
2 400.0
3 NaN
4 300.0
我想根据列表(值)中的值来转换此数据域(DF)。
values = [0,200,400,600]
在df中,第一个数字为250。它在列表values
中介于200和400之间,因此(| 200-250 |)/(400-200)= 0.25和(400-250)/(400 -200)= 0.75。如果缺少数据(np.nan),则必须用0填充行。我要以这种方式将其转换为代表此数据框。
所需数据框:
0 200 400 600
0 0.0 0.25 0.75 0.0
1 0.5 0.50 0.00 0.0
2 0.0 0.00 1.00 0.0
3 0.0 0.00 0.00 0.0
4 0.0 0.50 0.50 0.0
答案 0 :(得分:5)
这是使用s=pd.cut(df.A,values).dropna()
x=s.map(lambda x : x.left).astype(int).to_frame('V')
y=s.map(lambda x : x.right).astype(int).to_frame('V')
x['r']=(df.A-x.V)/(y.V-x.V)
y['r']=(y.V-df.A)/(y.V-x.V)
df1=pd.concat([x,y]).set_index('V',append=True).\
r.unstack(fill_value=0).\
reindex(columns=values,index=df.index,fill_value=0)
df1
Out[110]:
V 0 200 400 600
0 0.0 0.25 0.75 0.0
1 0.5 0.50 0.00 0.0
2 0.0 1.00 0.00 0.0
3 0.0 0.00 0.00 0.0
4 0.0 0.50 0.50 0.0
status:any; //<--it's necesary create a variable
submit() {
//add the asyncValidator
this.newPassword.setAsyncValidators(this.validateAsync())
//call to updateValueAndValidity
this.newPassword.updateValueAndValidity();
//store in a variable the status
this.status=this.newPassword.status
this.newPassword.statusChanges.pipe(
takeWhile(()=>this.status=='PENDING') //<--use takeWhile to unsubscribe
).subscribe((status) => {
this.newPassword.clearAsyncValidators();
this.status=this.newPassword.status
if (this.newPassword.valid) //<--check if is valid or not
alert('submit')
})
}
答案 1 :(得分:4)
设置
这里有很多事情要做。我想提出一种完全“矢量化”的方法,但是开销可能使该解决方案不是您要使用的性能最高的解决方案。选择一种方法之前,请确保在任何时间都包含此设置。
u = df['A'].values
v = np.asarray(values)
nan_u = np.isnan(u)
a = np.where(nan_u, 0, u)
d = v[1:] - v[:-1]
diffs = np.concatenate((d[:1], d))
s = np.searchsorted(v, a)
如果值随处可见,则可以使用矢量化方法计算比率,然后在有效范围之间进行屏蔽。
这假定所有非空值都在min(values)
和max(values)
之间。如果不满足此要求,那么创建掩码m
的步骤将失败,并出现索引错误。
m = np.zeros((u.shape[0], v.shape[0]), dtype='i1')
ar = np.arange(m.shape[0])
m[ar, s] = 1
m[ar, s-1] = 1
f = np.abs((v - a[:, None]) / diffs)
final = f * m
final[nan_u] = 0
final
array([[0. , 0.25, 0.75, 0. ],
[0.5 , 0.5 , 0. , 0. ],
[0. , 1. , 0. , 0. ],
[0. , 0. , 0. , 0. ],
[0. , 0.5 , 0.5 , 0. ]])
在此答案中,我不满意的第一步是在其中创造差异:
d = v[1:] - v[:-1]
diffs = np.concatenate((d[:1], d))
您实际上只有3个“差异”,但是由于形状原因您需要4个“差异”,因此可以将第一个差异或最后一个差异分别附加到数组的开头或结尾。似乎很笨拙,也许可以避免这种情况。