Python 使用条件对许多功能进行二值化

Python 使用条件对许多功能进行二值化,python,pandas,dataframe,frequency,categorical-data,Python,Pandas,Dataframe,Frequency,Categorical Data,我有一个包含数百个分类特征(数字)的熊猫数据框架。我只想在列中保留顶级值。我已经知道,每列中只有3或4个最常见的值,但我想自动选择它。我需要两种方法: 1) 只留下3个最频繁的值。概念:没有1, 2个或3个唯一值的列(每个列中有20个唯一值),所以不要考虑它。例如,如果你有几个第三名,就把它们都留下。例如: #使用value_counts()后,第1列 135 2 23 310 4.9 8 6.8 #在第2列上使用值_counts()后 0 23 215 1 15#两个第二名 4.9 5.3 6

我有一个包含数百个分类特征(数字)的熊猫数据框架。我只想在列中保留顶级值。我已经知道,每列中只有3或4个最常见的值,但我想自动选择它。我需要两种方法:

1) 只留下3个最频繁的值。概念:没有1, 2个或3个唯一值的列(每个列中有20个唯一值),所以不要考虑它。例如,如果你有几个第三名,就把它们都留下。例如:

#使用value_counts()后,第1列
135
2 23
310
4.9
8
6.8

#在第2列上使用值_counts()后
0 23
215
1 15#两个第二名
4.9
5.3
6.2

#在第1列上使用value_counts()后的结果
135
2 23
310
其他25#9+8+8

#在第2列上使用value_counts()后的结果
0 23
215
115
4.9
其他5#3+2

2) 根据需要在每列中保留尽可能多的值,以便剩余值的数量小于您决定保留的最后一个值的数量。例如:

#使用value_counts()后,第1列
135
2 23
310
4.3
8.2
6.1

#在第2列上使用值_counts()后
0 23
215
19
4.8
5.3
6.2

#在第1列上使用value_counts()后的结果
135
2 23
310
其他6#3+2+1

#在第2列上使用value_counts()后的结果
0 23
215
19
4.8
其他5#3+2


请两者都做。谢谢。

让我们用您的逻辑尝试一下udf:

def my_count(s):
    x = s.value_counts()
    if len(x) > 3:
        ret = x.iloc[:3].copy()
        ret.loc['other'] = x.iloc[3:].sum()
    else:
        ret = x
    return ret

df[['col1']].apply(my_count)
输出:

       col1
1        35
2        23
3        10
other     6

我将用两列数据展示我想在工作中使用的内容限制:在此解决方案中,第二、第三和第四位置的同时连接不会收集到同一单元格中。根据您的目的,您可能需要进一步自定义此行为

样本数据 共有2列,每个列包含26个类。一列是分类列,另一列是数字列。特意选择样本数据来展示领带的效果

import pandas as pd
import numpy as np

np.random.seed(2)  # reproducibility
df = pd.DataFrame(np.random.randint(65, 91, (1000, 2)), columns=["str", "num"])
df["str"] = list(map(chr, df["str"].values))

print(df)
    str  num
0     I   80
1     N   73
2     W   76
3     S   76
4     I   72
..   ..  ...
995   M   80
996   Q   70
997   P   66
998   I   87
999   F   83
[1000 rows x 2 columns]
期望功能
使用以下功能:

def myFilter(col, maxOther = 0):
    unq = col.value_counts()
    if maxOther == 0:    # Return 3 MFV
        thr = unq.unique()[:3][-1]
        otherCnt = unq[unq < thr].sum()
        rv = col[col.isin(unq[unq >= thr].index)]
    else:    # Drop last LFV, no more than maxOther
        otherCnt = 0
        for i in unq[::-1]:
            if otherCnt + i >= maxOther: break
            otherCnt += i
        thrInd = unq.size - i + 1
        rv = col[col.isin(unq[:thrInd].index)]
    rv = rv.reset_index(drop=True)
    # print(f'  Trace {col.name}\nunq:\n{unq}\notherCnt: {otherCnt}')
    return rv
def myFilter(col,maxOther=0):
unq=列值\计数()
如果maxOther==0:#返回3 MFV
thr=unq.unique()
otherCnt=unq[unq=thr].索引)]
否则:#放下最后一个LFV,不要超过maxOther
otherCnt=0
对于unq中的i[:-1]:
如果otherCnt+i>=maxOther:break
其他Cnt+=i
第三个=unq.size-i+1
rv=col[col.isin(unq[:thrInd].索引)]
rv=rv.重置索引(下降=真)
#打印(f'Trace{col.name}\nunq:\n{unq}\notherCnt:{otherCnt})
返回rv
我的假设是这两种变体之间的区别:

  • 返回3个最频繁值(MFV)
  • 删除最后一个不太频繁的(其他)值
由maxOther参数控制。 其默认值0表示“第一个变量”

因此,要测试这两种变体,请调用它:

  • df.apply(myFilter)
    对于第一个变量
  • df.apply(myFilter,maxOther=10)
    用于第二个变量
要查看跟踪打印输出,请取消对打印指令的注释
在函数中。

1。请以书面形式提供样本数据。2.你如何处理领带?比如说,如果有三个第三位的特征。3.如果一列中只有两个或一个功能,该怎么办?您提供了一个包含单个列的示例。请注意,是否离开或删除某些行取决于每列中的值是否分别属于每列中的最频繁值(MFV)。因此,请描述预期的解决方案应该如何工作,如果:1。某些列中的值属于MFV(查看此列中的值)。2.但其他列中的值不在MFV中(再次查看此(其他)列中的值)。@Valdi_-Bo谢谢,已修复。“我希望这是可能的。”BillHuang修复谢谢你的解决方案!
print(count_top_n(df, 3))
      str str_count       num num_count
1       V        52        71        51
2       Q        46        86        47
3  [B, K]  [46, 46]  [90, 67]  [46, 46]
4  (rest)       810    (rest)       810
def myFilter(col, maxOther = 0):
    unq = col.value_counts()
    if maxOther == 0:    # Return 3 MFV
        thr = unq.unique()[:3][-1]
        otherCnt = unq[unq < thr].sum()
        rv = col[col.isin(unq[unq >= thr].index)]
    else:    # Drop last LFV, no more than maxOther
        otherCnt = 0
        for i in unq[::-1]:
            if otherCnt + i >= maxOther: break
            otherCnt += i
        thrInd = unq.size - i + 1
        rv = col[col.isin(unq[:thrInd].index)]
    rv = rv.reset_index(drop=True)
    # print(f'  Trace {col.name}\nunq:\n{unq}\notherCnt: {otherCnt}')
    return rv