我有以下数据框:
MyAge Ages Names
7 [3,10,15] ['Tom','Jack','Sara']
6 [12,6,5,13] ['Nora','Betsy','John','Jill']
15 [24,3,65,15]['Tala','Jane','Bill','Mark']
我想生成一个新列,为Names
列表中的每一行生成一个随机选择的名称,以使具有该随机选择名称的人的年龄小于或等于{{1 }}。 MyAge
列反映了Ages
列中每个人的年龄。
因此可能的结果如下:
Names
答案 0 :(得分:1)
鉴于每行的年龄和名称的数目可以不同,请首先使用列表推导基于每行的年龄/名称的数目创建一个随机索引。然后使用更多列表推导为名称和年龄建立索引。最后,将结果分配回原始数据框。
# Sample data.
df = pd.DataFrame({
"MyAge": [7, 6, 15],
"Ages": [[3, 10, 15], [12, 6, 5, 13], [24, 3, 65, 15]],
"Names": [['Tom', 'Jack', 'Sara'], ['Nora', 'Betsy', 'John', 'Jill'], ['Tala', 'Jane', 'Bill', 'Mark']]
})
# Solution.
np.random.seed(0)
random_index = [np.random.randint(len(ages)) for ages in df['Ages']]
names = [names[idx] for idx, names in zip(random_index, df['Names'])]
ages = [ages[idx] for idx, ages in zip(random_index, df['Ages'])]
>>> df.assign(RandomName=names, RandomPersonAge=ages)
MyAge Ages Names RandomName RandomPersonAge
0 7 [3, 10, 15] [Tom, Jack, Sara] Tom 3
1 6 [12, 6, 5, 13] [Nora, Betsy, John, Jill] Jill 13
2 15 [24, 3, 65, 15] [Tala, Jane, Bill, Mark] Jane 3
要选择随机年龄以使其小于或等于MyAge
中的值,我们应该首先将数据展平。我们将使用条件嵌套列表理解来过滤数据,以便每一行都包含索引以及名称和等效年龄,其中年龄小于或等于MyAge
。然后,我们将从过滤后的数据中创建一个数据框,并根据第一列(即原始数据框索引的名称)设置索引。数据帧中的行通过sample(frac=1)
随机进行了混洗。然后,我们对索引进行分组并取得第一条随机行。然后,我们将结果连接回原始数据帧(默认情况下,连接是根据索引完成的。)
filtered_data = (
[(idx, name, age)
for idx, (my_age, ages, names) in df.iterrows()
for age, name in zip(ages, names)
if age <= my_age]
)
random_names_and_ages = (
pd.DataFrame(filtered_data, columns=[df.index.name, 'RandomName', 'RandomPersonAge'])
.set_index(df.index.name)
.sample(frac=1) # Randomly huffle the rows in the dataframe.
.groupby(level=0)[['RandomName', 'RandomPersonAge']] # Groupby 'ID' and take the first random row.
.first()
)
>>> df.join(random_names_and_ages)
MyAge Ages Names RandomName \
0 7 [3, 10, 15] [Tom, Jack, Sara] Tom
1 6 [12, 6, 5, 13] [Nora, Betsy, John, Jill] John
2 15 [24, 3, 65, 15] [Tala, Jane, Bill, Mark] Jane
RandomPersonAge
0 3
1 5
2 3