计算列值满足不同条件的时间百分比

时间:2018-03-07 00:39:01

标签: python pandas dataframe

我有一个类似下面的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

3 个答案:

答案 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)