同时使用zip和百分位数- Python



我正在使用一个panda数据框架,其中我将列表作为单个单元格元素(用于少数列)。我想检查一列中列表中每个元素的条件,并从另一列中选择相应的列表元素。我知道使用zip命令可以很容易地做到这一点,例如:

p = 5 ; q = 6;DF['Column3'] = [[b for a, b in zip(x, y) if a > p and a <q ] for x, y in zip(DF['Column1'], DF['Column2'])]然而,我不确定如何在这里使用百分位数,即,而不是固定的p和q,我想使用列表的一些百分位数值(例如50(相当于p)百分位数到90百分位数(相当于q))。

因此,对于列中的每个单元格(每个单元格组成一个列表),它应该计算preentile值并检查另一列中其他列表(来自相应的单元格)中的相应列表元素。

用一个例子(假设是DF)来解释这个问题:

Column203.45.7(2.1,2.9,5.2,6.8)(2.5,3.4,1.2,5.1)

您可以使用numpy.percentile来获取您的范围的两个值。然后,跨列使用列表推导(通过传递axis=1)。

作为一行代码,可以这样做:

df['Column3'] = (df.assign(Column3=df['Column1'].apply(lambda x: np.percentile(x, [50, 90])))
.apply(lambda x: [b for (a,b) in zip(x['Column1'], x['Column2']) 
if x['Column3'][0] < a < x['Column3'][1]], axis=1))

将步骤分解为更详细的内容:

df = pd.DataFrame(
{'A' : [3.4,4],
'B' : [5.7, 1.7],
'Column1' : [[2.1, 2.9, 5.2, 6.8], [1.1, 2.5, 5.6, 11.5, 15.6, 21.5]],
'Column2' : [[2.5,3.4,1.2,5.1],[12.15,1.58,5.4,1.2,34.2,67.2]]})
df['Column3'] = df['Column1'].apply(lambda x: np.percentile(x, 50))
df['Column4'] = df['Column1'].apply(lambda x: np.percentile(x, 90))
df['Column5'] = df.apply(lambda x: [b for (a,b) in zip(x['Column1'], x['Column2']) 
if x['Column3'] < a < x['Column4']], axis=1)
df
Out[1]: 
A    B                            Column1  
0  3.4  5.7               [2.1, 2.9, 5.2, 6.8]   
1  4.0  1.7  [1.1, 2.5, 5.6, 11.5, 15.6, 21.5]   
Column2  Column3  Column4      Column5  
0                 [2.5, 3.4, 1.2, 5.1]     4.05     6.32        [1.2]  
1  [12.15, 1.58, 5.4, 1.2, 34.2, 67.2]     8.55    18.55  [1.2, 34.2]  

从这里,你可以做:

df = df.drop(['Column3', 'Column4'], axis=1)

最新更新