熊猫:向现有数据框添加新行,使所有列的分布保持相同

时间:2018-07-19 05:54:34

标签: python pandas dataframe

我正在使用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大小的同时保持此分布不变。

2 个答案:

答案 0 :(得分:0)

以下函数舍入每个唯一值 的目标行数,因此与仅复制整个数据帧相比,分布更接近所需的行数。在以下示例中,对于乘数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 

答案 1 :(得分:0)

一种简单的方法是将所有行重复一定次数,以达到所需的观察次数。

比方说,您有一个数据框df,并且您想要num_reqd个观测值。根据{{​​1}}的观察,所有重复(num_reqd//df.shape[0])次的行都应该给您一些信息。

num_reqd

但是,如果您想进一步混合数据,可以使用import pandas as pd new_df = pd.concat([df] * (num_reqd//df.shape[0]), axis=1) 来对列中的值进行混洗。

numpy

如果您也想保留原始观测值,则可以从import numpy as np new_df.apply(np.random.shuffle, axis=0) 合并值。

df