首页 > 解决方案 > 如果数据帧的值属于同一区间,则将数据帧的值替换为区间的上限

问题描述

我有一个数据框 main_df。给定步长 1,我生成了半开或半闭区间。数据和代码如下。

mainList= [[0.3, 0.2, 0.2, 0.5, 0.2, 0.3, 0. , 0.2, 0.4, 0.2],
      [0.2, 0.1, 0.2, 0.5, 0.2, 0.2, 0. , 0.2, 0.4, 0.1], 
      [0.2, 0.1, 0.2, 0.6, 0.2, 0.2, 0. , 0.2, 0.3, 0. ],
      [0.2, 0.1, 0.3, 0.6, 0.2, 0.2, 0. , 0.2, 0.2, 0.1],
      [0.2, 0.2, 1.2, 0.7, 0.2, 0.2, 0. , 0.2, 0.2, 0. ],
      [1.2, 0.1, 0.8, 2.1, 0.2, 0.1, 0. , 0.2, 0.1, 0.1],
      [1.3, 0.3, 0.2, 2. , 0.2, 0.2, 0.1, 0.2, 0.1, 0. ], 
      [1.3, 0.3, 0.2, 2.2, 0.2, 0.8, 0.2, 0.2, 0.2, 0. ],
      [1.2, 0.2, 0.2, 2.6, 0.2, 2. , 0.1, 0.2, 0.6, 0. ],
      [1.2, 0.9, 0.2, 3.1, 1.9, 1.6, 0.1, 0.2, 0.5, 0.1]]

main_df = pd.DataFrame(mainList)

val_min = min(main_df.min())
x = np.arange(val_min, val_max, 1)
interval_list = []
if len(x)/2 == 0:

     for i in range(0, len(x)):
         x1 = list(x[i:i+2])
         interval_list.append(x1)


else:
    for i in range(0, len(x)-1):
        x1 = list(x[i:i+2])
        interval_list.append(x1)

half_open_intervalsList = []
for j in interval_list:
    k = pd.Interval(j[0], j[1])
    half_open_intervalsList.append(k)

半开区间列表如下:

[(0.0, 1.0], (1.0, 2.0], (2.0, 3.0]]

如果值属于相同的间隔,我想用间隔的上限替换 mainList/main_df 的值。请注意,如果 mainList 中的值不属于这些区间,则它们将保持原样。

我尝试了以下代码段,但它没有输出 outputList 中给出的所需结果。

for ls in mainList:
for m in ls:
    sub_list = []
    for interval in range(0, len(half_open_intervalsList)):
        if m in half_open_intervalsList[interval]:
            #print(m)
            z = main_df.replace(element, half_open_intervalsList[interval].right)
            #sub_list.append(z)

outputList= [[1, 1, 1, 1, 1, 1, 0. , 1, 1, 1],
      [1, 1, 1, 1, 1, 1, 0. , 1, 1, 1], 
      [1, 1, 1, 1, 1, 1, 0. , 1, 1, 0. ],
      [1, 1, 1, 1, 1, 1, 0. , 1, 1, 1],
      [1, 1, 2, 1, 1, 1, 0. , 1, 1, 0. ],
      [2, 1, 1, 3, 1, 1, 0. , 1, 1, 1],
      [2, 1, 1, 2 , 1, 1, 1, 1, 1, 0. ], 
      [2, 1, 1, 3, 1, 1, 1, 1, 1, 0. ],
      [2, 1, 1, 3, 1, 2 , 1, 1, 1, 0. ],
      [2, 1, 1, 3.1, 2, 2, 1, 1, 1, 1]]

标签: pythonpandaslistdataframe

解决方案


您可以从半开区间列表中创建一个映射系列,然后使用.apply+map将数据框中的值与映射系列中的相应值映射,最后用原始数据框中的值填充NaN值(无法映射的值) :

m = pd.Series([i.right for i in half_open_intervalsList], half_open_intervalsList)

main_df.apply(lambda s: s.map(m)).fillna(main_df)
# OR main_df.stack().map(m).unstack().fillna(main_df)

     0    1    2    3    4    5    6    7    8    9
0  1.0  1.0  1.0  1.0  1.0  1.0  0.0  1.0  1.0  1.0
1  1.0  1.0  1.0  1.0  1.0  1.0  0.0  1.0  1.0  1.0
2  1.0  1.0  1.0  1.0  1.0  1.0  0.0  1.0  1.0  0.0
3  1.0  1.0  1.0  1.0  1.0  1.0  0.0  1.0  1.0  1.0
4  1.0  1.0  2.0  1.0  1.0  1.0  0.0  1.0  1.0  0.0
5  2.0  1.0  1.0  3.0  1.0  1.0  0.0  1.0  1.0  1.0
6  2.0  1.0  1.0  2.0  1.0  1.0  1.0  1.0  1.0  0.0
7  2.0  1.0  1.0  3.0  1.0  1.0  1.0  1.0  1.0  0.0
8  2.0  1.0  1.0  3.0  1.0  2.0  1.0  1.0  1.0  0.0
9  2.0  1.0  1.0  3.1  2.0  2.0  1.0  1.0  1.0  1.0

推荐阅读