我需要一个DataFrame
与r
行和动态数量的列(基于组)。输入count
列指定在新DataFrame
中需要多少个True
值。我目前的实现创建了一个临时DataFrame
,其中一行包含df中每个group
的True
值,然后explode()
是该临时 Dataframe 。最后,它按count
分组并聚合为结果df
输入
--
| group | count | ...
| A | 2 |
| B | 0 |
| C | 4 |
| D | 1 |
我需要用这个值填充新的DataFrame
随机(c
-(列)值是动态的,与名称相同)
预期输出
--
| 一个|B级|C类|D级|
| - -----|- -----|- -----|- -----|
| NaN| NaN| * * 真**|* * 真**|
| * * 真**| NaN| * * 真**| NaN|
| NaN| NaN| NaN| NaN|
| NaN| NaN| * * 真**| NaN|
| * * 真**| NaN| * * 真**| NaN|
我认为可以添加一个随机的长度集,从1到**r
**,然后扩展等等。就用这个值来表示agg(sum)。
我的代码
--
inputs = [
{"group": "A", "count": 2},
{"group": "B", "count": 0},
{"group": "C", "count": 4},
{"group": "D", "count": 1},
]
df = pd.DataFrame(inputs)
def expand(count:int, group: str) -> pd.DataFrame:
"""expands DF by counts"""
count = int(round(count))
df1 = pd.DataFrame([{group: True}])
# I'm thinking here i need to add random seed
df1 = df1.assign(count = [list(range(1, count+1))])\
.explode('count')\
.reset_index(drop=True)
return df1
def creator(df: pd.DataFrame) -> pd.DataFrame:
"""create new DF for every group value(count)"""
dfs = [expand(r, df['group'].values[0]) for r in list(df['count'].values)]
df = pd.concat(dfs, ignore_index=True)
return df
df.groupby('group', as_index=False)\
.apply(creator)\
.drop('count', axis=1)\
# and groupby my seed
.groupby(level=1)\
.agg(sum)
我试着声明我的问题,如果它会有帮助:
1.在pandas中有没有什么方法可以让这变得更容易/更好?
1.如何在expand()
函数中进行随机计数并分配它们?
1.这是一种用NaN
创建大小为DataFrame
的方法,然后随机地将我的值放在那里(比如pd.where
或其他东西)吗?
PS:这是我第一次问问题,所以希望我已经提供了足够的信息!
2条答案
按热度按时间gjmwrych1#
一个纯粹的 pandas 解决方案是使用
sample
:输出:
一个简单的方法是 * 引导 * 一个预空
DataFrame
,同时随机选择/拾取一个坐标[index, column]
:5f0d552i2#
步骤:
1.从字典列表中定义DataFrame
r
是最终DataFrame中的行数1.创建一个字典
group_indexes
,每个键是一个group
名称,每个值是随机选择的唯一行索引。索引的数量是count
和r
中的最小值。1.创建空DataFrame
df_empty
,其中r
行和列由唯一的group
名称定义。1.遍历
df_empty
中的每一列。如果column name在group_indexes
中,则它将列中那些行索引处的值设置为True。df_filled
是通过将df_empty
中的所有其他非True值替换为NaN来创建的。这是另一个我认为更简单的方法:
这首先初始化一个用NaN填充的DataFrame。然后,对于每个组,它根据组的计数随机选择唯一的索引,并将这些位置设置为True。