Python 熊猫箱内部零填充

Python 熊猫箱内部零填充,python,python-3.x,pandas,numpy,padding,Python,Python 3.x,Pandas,Numpy,Padding,我有一个熊猫数据帧df,如下所示: df = pd.DataFrame(data={"Group": ["a", "a", "a", "b", "b"], "Index": [1, 8, 9, 1, 3], "Value": [23.2, 1.

我有一个熊猫数据帧
df
,如下所示:

df = pd.DataFrame(data={"Group": ["a", "a", "a", "b", "b"], 
                       "Index": [1, 8, 9, 1, 3], 
                       "Value": [23.2, 1.2, 1.7, 21.9, 432.2]})
>>> print(df)

  Group  Index  Value
0     a      1   23.2
1     a      8    1.2
2     a      9    1.7
3     b      1   21.9
4     b      3  432.2
我希望获得以下信息(空行用于说明):

基本上,我想在“Value”列中引入零填充,以便所有“Index”容器[1,2,3]、[4,5,6]和[7,8,9]都正好用3个值填充。“索引”整数在组中只能出现一次,范围从1到9。如果bin不包含任何“索引”整数,则不应进行填充。“a组”和“b组”的行应单独处理

这就是我取得的成绩:

a_group = df.groupby("Group")
for _, group in a_group:
    group["Bin"] = pd.cut(group["Index"], bins=list(range(1, 12, 3)), right=False)
    print(group)
    print("\n")

  Group  Index  Value      Bin
0     a      1   23.2   [1, 4)
1     a      8    1.2  [7, 10)
2     a      9    1.7  [7, 10)


  Group  Index  Value     Bin
3     b      1   21.9  [1, 4)
4     b      3  432.2  [1, 4)

在这一点上,我不知道还能做些什么,希望能得到一些帮助。提前谢谢。

这就是你要找的吗

g = df['Group'].unique()
i = range(1,df['Index'].max()+1)

df2 = df.set_index(['Group','Index']).reindex(pd.MultiIndex.from_product([g,i])).assign(cc = lambda x: (x.groupby(level=0).cumcount())//3).rename_axis(['Group','Index'],axis=0)
df2.loc[~df2['Value'].isna().groupby([pd.Grouper(level=0),df2['cc']]).transform('all')].reset_index().fillna(0).drop('cc',axis=1)

这就是你要找的吗

g = df['Group'].unique()
i = range(1,df['Index'].max()+1)

df2 = df.set_index(['Group','Index']).reindex(pd.MultiIndex.from_product([g,i])).assign(cc = lambda x: (x.groupby(level=0).cumcount())//3).rename_axis(['Group','Index'],axis=0)
df2.loc[~df2['Value'].isna().groupby([pd.Grouper(level=0),df2['cc']]).transform('all')].reset_index().fillna(0).drop('cc',axis=1)

@rhug123所接受的答案是一个非常好的答案,但我在下面提出了一个替代解决方案。我的解决方案的核心思想是创建一个bin标识符/键,它将帮助选择目标索引

TL;DR 逐步解释。 首先创建一个临时数据框,作为原始
df
缺少的索引值的占位符

max_index_value = 9
bin_size = 3

df_temp = pd.DataFrame({"Group":np.repeat(df['Group'].unique(), max_index_value)})
df_temp['Index'] = df_temp.groupby(['Group']).cumcount() + 1

# getting the values from original dataset
df_temp = df_temp.merge(df, how='left', on=['Group', 'Index'])
接下来,添加bin键,该键用于标记bin以供以后分组

# the bin size defines the available key values
df_temp['bin_key'] = df_temp.groupby(['Group']).cumcount() // bin_size
然后,这里是一个棘手的部分,我们使用列
group
bin_key
上的group函数和
max()
函数来选择最终结果中应该出现哪些组和键

df_bin_key = df_temp.groupby(['Group', 'bin_key'])[['Value']].max().reset_index().dropna().drop(columns=['Value'])
最后,我们使用
bin键
df_temp
左键连接到
df_bin_键
中,以达到预期的结果

df_final = df_bin_key.merge(df_temp, how='left', on=['Group', 'bin_key']).fillna(0).drop(columns=['bin_key'])

PS:为了便于解释,我将此解决方案分解为多个步骤,这里的一些步骤可以重写并组合成一行。

@rhug123接受的答案非常好,但我在下面提出了一个替代解决方案。我的解决方案的核心思想是创建一个bin标识符/键,它将帮助选择目标索引

TL;DR 逐步解释。 首先创建一个临时数据框,作为原始
df
缺少的索引值的占位符

max_index_value = 9
bin_size = 3

df_temp = pd.DataFrame({"Group":np.repeat(df['Group'].unique(), max_index_value)})
df_temp['Index'] = df_temp.groupby(['Group']).cumcount() + 1

# getting the values from original dataset
df_temp = df_temp.merge(df, how='left', on=['Group', 'Index'])
接下来,添加bin键,该键用于标记bin以供以后分组

# the bin size defines the available key values
df_temp['bin_key'] = df_temp.groupby(['Group']).cumcount() // bin_size
然后,这里是一个棘手的部分,我们使用列
group
bin_key
上的group函数和
max()
函数来选择最终结果中应该出现哪些组和键

df_bin_key = df_temp.groupby(['Group', 'bin_key'])[['Value']].max().reset_index().dropna().drop(columns=['Value'])
最后,我们使用
bin键
df_temp
左键连接到
df_bin_键
中,以达到预期的结果

df_final = df_bin_key.merge(df_temp, how='left', on=['Group', 'bin_key']).fillna(0).drop(columns=['bin_key'])


PS:为了便于解释,我将此解决方案分解为多个步骤,这里的一些步骤可以重写并组合成一行。

在您的预期输出中-组
a
的索引
4,5,6
的值在哪里?你的问题定义不清楚,为什么
1,2,3
但是
7,8,9
,而不是
8,9,10
?嘿,谢谢你的回答。正如我提到的,如果一个箱子里没有值,就不应该进行填充“a”组中不存在“4,5,6”*好的,对不起。因此,垃圾箱的间隔长度为3。但是这些值可以是1-9之间的任何整数。例如,5是4,5,6料仓的一部分,但在该特定df中不存在。因此,在4,5,6中不应进行填充。此外,值只能在组中出现一次。如果您在注释中给出了示例,那么是否存在3、4、5个bin?或者垃圾箱只能是[1,2,3]、[4,5,6]、[7,8,9]?只能是[1,2,3]、[4,5,6]、[7,8,9]。谢谢你的邀请。在您的预期输出中-组
a
的索引
4,5,6
的值在哪里?你的问题定义不清楚,为什么
1,2,3
但是
7,8,9
,而不是
8,9,10
?嘿,谢谢你的回答。正如我提到的,如果一个箱子里没有值,就不应该进行填充“a”组中不存在“4,5,6”*好的,对不起。因此,垃圾箱的间隔长度为3。但是这些值可以是1-9之间的任何整数。例如,5是4,5,6料仓的一部分,但在该特定df中不存在。因此,在4,5,6中不应进行填充。此外,值只能在组中出现一次。如果您在注释中给出了示例,那么是否存在3、4、5个bin?或者垃圾箱只能是[1,2,3]、[4,5,6]、[7,8,9]?只能是[1,2,3]、[4,5,6]、[7,8,9]。谢谢你的邀请。应该说得更清楚。是的!太完美了。我将不得不了解您的代码中到底发生了什么,但它满足了我的需要。非常感谢,是的!太完美了。我将不得不了解您的代码中到底发生了什么,但它满足了我的需要。非常感谢。嘿,muito obrigado@rhug123给了我一个快速的解决方案,但不知何故它在我的实际数据集上不起作用(这只是一个示例)。您的代码运行良好,但对于更大的数据帧,我在一个组中得到了双/三/多个“索引”整数。试图弄清楚发生了什么好吧我的数据集有问题。我有两个组而不是一个,所以如果我只使用一个组,我会得到非唯一的“索引”整数。我将尝试解决此问题。@SandorAlbert您所说的多个“索引”整数是什么意思,您的意思是对于给定的组值,索引值可以重复自身(例如,值“a”与多个“1”索引相关)?你能举个例子吗?在您提供的这个示例中,有两个
Group
值(
a
b
),那么您所说的两个组而不是一个组是什么意思呢?很抱歉造成混淆。我所说的两个组是指两个组列。如果是这样,如果应用或@rhug123代码,将获得非唯一的“索引”项。我可以通过简单地将第二个组列添加到@rhug123 code:
g=df['Group1'].unique()h=df['Group2'].u来解决这个问题