首页 > 解决方案 > Pandas:向现有数据框添加新行,在所有列中保持相同的分布

问题描述

我正在使用熊猫数据框。我想将我的数据框的大小从 1000 增加到 4432(不完全是 n 倍,n 是自然数)。我想确保增加大小后每列中的值分布保持不变。例如,如果我有Car给定分布的列名,现有 100 行。

Maruti  30%
Ford    10%
Tata    40%
Others  10%

我想在将大小增加到 4432 后保持这个份额不变

该列可以是范围、数字、分类。更多的例子是Age像这样的分布

20-30   20%
30-40   40%
40-50   25%
50-60   15%

同样,我想在增加 Dataframe 大小的同时保持这个分布不变。

标签: pythonpandasdataframe

解决方案


以下函数对每个唯一值的目标行数进行四舍五入,因此与仅复制整个数据帧相比,分布更接近所需的分布。在以下示例中,对于乘数 1.5,您实际上可以保留分布,即使简单concat不会为您1.5x提供原始数据帧。

def increase_df(df, column, multiplier):
    new_value_counts = (df[column].value_counts() * multiplier).apply(lambda value: int(round(value)))
    values = sum(([value] * count for value, count in new_value_counts.to_dict().items()), [])
    return pd.DataFrame(values)

df = pd.DataFrame(["Mumbai"] * 4 + ["Kolkata"] * 2 + ["Chennai"] * 2 + ["Delhi"] * 4, columns=['city']) 
print df
       city
0   Mumbai 
1   Mumbai 
2   Mumbai 
3   Mumbai 
4   Kolkata
5   Kolkata
6   Chennai
7   Chennai
8   Delhi  
9   Delhi  
10  Delhi  
11  Delhi 

# here the distribution can be preserved exactly
print increase_df(df, 'city', 1.5)
          0
0   Kolkata
1   Kolkata
2   Kolkata
3   Chennai
4   Chennai
5   Chennai
6   Delhi  
7   Delhi  
8   Delhi  
9   Delhi  
10  Delhi  
11  Delhi  
12  Mumbai 
13  Mumbai 
14  Mumbai 
15  Mumbai 
16  Mumbai 
17  Mumbai 

# here it can't, because the target number of rows per value is fractional. 
# The function rounds that number to the nearest int, so the distribution is as close to the original one as it can get.
print increase_df(df, 'city', 1.8)

          0
0   Kolkata
1   Kolkata
2   Kolkata
3   Kolkata
4   Chennai
5   Chennai
6   Chennai
7   Chennai
8   Delhi  
9   Delhi  
10  Delhi  
11  Delhi  
12  Delhi  
13  Delhi  
14  Delhi  
15  Mumbai 
16  Mumbai 
17  Mumbai 
18  Mumbai 
19  Mumbai 
20  Mumbai 
21  Mumbai 

推荐阅读