我有一个类似下面的DataFrame,只有大约25列和3000行。我需要第二个DF,它显示df_A中每列中所有行的> = df_B中的目标的百分比。
例如,在df_A中,列d02是> = .04,三次中有三次(列的len),因此应该在df_B中反映为60%。
我知道如何分别进行比较和百分比,但我迷失了如何把所有东西放在一起并填充新的DF。
df_A
d01 d02 d03
0 0.028 0.021 0.028
1 0.051 0.063 0.093
2 0.084 0.084 0.084
3 0.061 0.061 0.072
4 0.015 0.015 0.015
目标...
df_B
target d01 d02 d03
.02 p p p
.04 p .60 p
.06 p p p
.08 p p p
.15 p p p
.20 p p p
.25 p p p
.30 p p p
答案 0 :(得分:1)
DataFrame
。df_A = pd.DataFrame(data = {
"d01": [ 0.028, 0.051, 0.084, 0.061, 0.015],
"d02": [ 0.021, 0.063, 0.084, 0.061, 0.015],
"d03": [ 0.028, 0.093, 0.084, 0.072, 0.015] })
target = [.02, .04, .06, .08, .15, .20, .25, .30]
dic = {key: [] for key in df_A}
for t in target:
for key in dic:
s = 0
for val in df_A[key]:
if val >= t:
s += 1
dic[key].append(s / len(df_A[key]))
df_B = pd.DataFrame(data = dic, index = target)
df_B
d01 d02 d03
0.02 0.8 0.8 0.8
0.04 0.6 0.6 0.6
0.06 0.4 0.6 0.6
0.08 0.2 0.2 0.4
0.15 0.0 0.0 0.0
0.20 0.0 0.0 0.0
0.25 0.0 0.0 0.0
0.30 0.0 0.0 0.0
答案 1 :(得分:1)
假设您(从路易斯复制了示例数据):
df_A = pd.DataFrame(data = {
"d01": [ 0.028, 0.051, 0.084, 0.061, 0.015],
"d02": [ 0.021, 0.063, 0.084, 0.061, 0.015],
"d03": [ 0.028, 0.093, 0.084, 0.072, 0.015] })
target = [.02, .04, .06, .08, .15, .20, .25, .30]
df_B = pd.DataFrame(index=target, columns=df_A.columns).rename_axis('target',axis=0)
您可以使用lambda函数计算百分比。
df_B.apply(lambda x: df_A.ge(x.name).sum().div(len(df_A)), axis=1).reset_index()
Out[249]:
target d01 d02 d03
0 0.02 0.8 0.8 0.8
1 0.04 0.6 0.6 0.6
2 0.06 0.4 0.6 0.6
3 0.08 0.2 0.2 0.4
4 0.15 0.0 0.0 0.0
5 0.20 0.0 0.0 0.0
6 0.25 0.0 0.0 0.0
7 0.30 0.0 0.0 0.0
答案 2 :(得分:1)
一种方法是使用numpy
:
a, t, n = df_A.values, df_T.values, len(df_A.index)
res = np.zeros((len(df_T.index), len(df_A.columns)))
for i in range(res.shape[0]):
for j in range(res.shape[1]):
res[i, j] = np.sum(a[:, j] >= t[i]) / n
result = df_T.join(pd.DataFrame(res, columns=df_A.columns))
<强>设置强>
DF_A:
d01 d02 d03
0 0.028 0.021 0.028
1 0.051 0.063 0.093
2 0.084 0.084 0.084
3 0.061 0.061 0.072
4 0.015 0.015 0.015
df_T:
target
0 0.02
1 0.04
2 0.06
3 0.08
4 0.15
5 0.20
6 0.25
7 0.30
<强>结果强>
target d01 d02 d03
0 0.02 0.8 0.8 0.8
1 0.04 0.6 0.6 0.6
2 0.06 0.4 0.6 0.6
3 0.08 0.2 0.2 0.4
4 0.15 0.0 0.0 0.0
5 0.20 0.0 0.0 0.0
6 0.25 0.0 0.0 0.0
7 0.30 0.0 0.0 0.0
效果基准
可以使用numpy
进一步优化numba
版本。
%timeit allen(df_A, target) # 40ms
%timeit louis(df_A, target) # 7.79ms
%timeit jpp(df_A, df_T) # 4.29ms
df_A = pd.concat([df_A]*10)
df_T = pd.concat([df_T]*5)
target = [.02, .04, .06, .08, .15, .20, .25, .30] * 5
def allen(df_A, target):
df_B = pd.DataFrame(index=target, columns=df_A.columns).rename_axis('target',axis=0)
return df_B.apply(lambda x: df_A.ge(x.name).sum().div(len(df_A)), axis=1).reset_index()
def jpp(df_A, df_T):
a, t, n = df_A.values, df_T.values, len(df_A.index)
res = np.zeros((len(df_T.index), len(df_A.columns)))
for i in range(res.shape[0]):
for j in range(res.shape[1]):
res[i, j] = np.sum(a[:, j] >= t[i]) / n
return df_T.join(pd.DataFrame(res, columns=df_A.columns))
def louis(df_A, target):
dic = {key: [] for key in df_A}
for t in target:
for key in dic:
s = 0
for val in df_A[key]:
if val >= t:
s += 1
dic[key].append(s / len(df_A[key]))
return pd.DataFrame(data = dic, index = target)