正如标题所指定的,我正在尝试获取重复行的数据框。 决定执行N次重复的因素是基于原始数据帧中存在的特定列的唯一值的长度。 执行重复过程之后,我想创建一个新列,将原始数据帧的特定列的所有相同唯一值应用于创建的每个新行。
我知道这有点令人困惑,但是我无法尝试以更好的方式来揭露我的怀疑。因此,为简化您对我所需方法的理解,下面是我的数据框和所需输出数据框的简短示例:
>> Original Dataframe
Samp Age Cs
1 A 51 msi
2 B 62 cin
3 C 55 msi
4 D 70 ebv
5 E 56 gs
....
如您所见,我的 Cs 列具有4个唯一值(对于不同的数据框,它们可能并不总是相同的)。因此,我的目标是获得具有以下结构的数据框:
>> Desired Dataframe
Samp Age Cs
1 A 51 msi
1 A 51 cin
1 A 51 ebv
1 A 51 gs
2 B 62 cin
2 B 62 msi
2 B 62 gs
2 B 62 ebv
3 C 55 msi
3 C 55 cin
3 C 55 ebv
3 C 55 gs
4 D 70 ebv
4 D 70 cin
4 D 70 msi
4 D 70 gs
5 E 56 gs
5 E 56 cin
5 E 56 msi
5 E 56 ebv
....
如您所见,在我想要的数据框中,所有行都重复了4次(等于唯一的 Cs 列值的数量),但 Cs 列(将其所有唯一值应用于不同的行)。
答案 0 :(得分:1)
您可以同时使用pivot
函数和fillna
这两种方法来计算结果:
df.pivot('Cs', 'Samp', 'Age').fillna(method='ffill').fillna(method='bfill').unstack().to_frame('Age').reset_index()
答案 1 :(得分:1)
一种解决方案是将'Cs'
转换为Categorical。然后使用GroupBy
+ first
:
df['Cs'] = df['Cs'].astype('category')
res = df.groupby(['Samp', 'Cs']).first().reset_index()
res['Age'] = res.groupby('Samp')['Age'].transform('first').astype(int)
结果
Samp Cs Age
0 A cin 51
1 A ebv 51
2 A gs 51
3 A msi 51
4 B cin 62
5 B ebv 62
6 B gs 62
7 B msi 62
8 C cin 55
9 C ebv 55
10 C gs 55
11 C msi 55
12 D cin 70
13 D ebv 70
14 D gs 70
15 D msi 70
16 E cin 56
17 E ebv 56
18 E gs 56
19 E msi 56
答案 2 :(得分:1)
使用numpy.unique
创建另一个DataFrame并执行合并,这将产生两个框架的笛卡尔积。
s = pd.Series(np.unique(df.Cs.values)).rename('Cs').to_frame()
pd.merge(
df.iloc[:, :2].assign(key=0),
s.assign(key=0),
on='key'
).drop('key', 1)
Samp Age Cs
0 A 51 cin
1 A 51 ebv
2 A 51 gs
3 A 51 msi
4 B 62 cin
5 B 62 ebv
6 B 62 gs
7 B 62 msi
8 C 55 cin
9 C 55 ebv
10 C 55 gs
11 C 55 msi
12 D 70 cin
13 D 70 ebv
14 D 70 gs
15 D 70 msi
16 E 56 cin
17 E 56 ebv
18 E 56 gs
19 E 56 msi
时间
tmp = pd.DataFrame({
'Samp': np.arange(10000),
'Age': np.arange(10000),
'Cs': np.repeat(df.Cs, 2000)
})
In [90]: %%timeit
...: s = pd.Series(np.unique(tmp.Cs.values)).rename('Cs').to_frame()
...: pd.merge(
...: tmp.iloc[:, :2].assign(key=0),
...: s.assign(key=0),
...: on='key'
...: ).drop('key', 1)
...:
10.3 ms ± 92.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [91]: %%timeit
...: tmp['Cs'] = tmp['Cs'].astype('category')
...:
...: res = tmp.groupby(['Samp', 'Cs']).first().reset_index()
...: res['Age'] = res.groupby('Samp')['Age'].transform('first').astype(int)
...:
...:
51.5 ms ± 1.69 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)