Python 在group by中创建具有条件的random.randint?

Python 在group by中创建具有条件的random.randint?,python,pandas,Python,Pandas,我有一个名为“cars”的专栏,希望使用random.randint()创建另一个名为“persons”的专栏,我有: dat['persons']=np.random.randint(1,5,len(dat)) 这是为了让我可以把使用这些的人数,但我会 想知道如何设置条件,以便在“suv”类别中仅生成4到9的数字,例如 cars | persons suv 4 sedan 2 truck 2 suv 1 suv 5 您可以为序列

我有一个名为“cars”的专栏,希望使用random.randint()创建另一个名为“persons”的专栏,我有:

dat['persons']=np.random.randint(1,5,len(dat))
这是为了让我可以把使用这些的人数,但我会 想知道如何设置条件,以便在“suv”类别中仅生成4到9的数字,例如

cars | persons
suv     4
sedan   2
truck   2         
suv     1      
suv     5

您可以为序列创建索引,其中匹配的行具有
True
,其他所有行具有
False
。然后,您可以使用指定给与该索引匹配的行来选择行;然后仅为这些选定行生成值的数量:

m = dat['cars'] == 'suv'
dat.loc[m, 'persons'] = np.random.randint(4, 9, m.sum())
您还可以在
cars
系列上使用
apply
创建新列,在每次调用中创建一个新的随机值:

dat['persons'] = dat.cars.apply(
    lambda c: random.randint(4, 9) if c == 'suv' else random.randint(1, 5))

但这必须为每一行进行单独的函数调用。使用面具会更有效率。

也许有一种方法可以使用比我更聪明的groupby之类的东西来实现这一点,但我的方法是构建一个函数,并将其应用到您的cars列。这是非常灵活的-如果您希望每辆车都有不同的功能,则可以轻松构建更复杂的逻辑:

def get_persons(car):
    if car == 'suv':
        return np.random.randint(4, 9)
    else:
        return np.random.randint(1, 5)
dat['persons'] = dat['cars'].apply(get_persons)
或者以一种更圆滑但不太灵活的方式:

dat['persons'] = dat['cars'].apply(lambda car: np.random.randint(4, 9) if car == 'suv' else np.random.randint(1, 5))

选项1
因此,您生成的随机数介于1和5之间,而SUV类别中的数字应该介于4和9之间。这仅仅意味着你可以生成一个随机数,然后在所有属于SUV类别的随机数中加上4

df = df.assign(persons=np.random.randint(1,5, len(df)))
df.loc[df.cars == 'suv', 'persons'] += 4

df

    cars  persons
0    suv        7
1  sedan        3
2  truck        1
3    suv        8
4    suv        8

选项2
另一种选择是使用
np.where
-

df.persons = np.where(df.cars == 'suv', 
                      np.random.randint(5, 9, len(df)), 
                      np.random.randint(1, 5, len(df)))
df

    cars  persons
0    suv        8
1  sedan        1
2  truck        2
3    suv        5
4    suv        6

这将比其他解决方案慢得多。这应该说明原因: