Skip to main content
 首页 » 编程设计

python之根据 Pandas 中特定键的出现将长序列转换为数据框

2025年05月04日15三少

首先,如果问题主题看起来含糊不清,我们深表歉意。我会尽量说清楚。 我有一个像这样的 Pandas 系列:

A 
a1 
b1 
c1 
B 
a2 
b2 
c2 

我们需要形成一个数据框,其中 {A,B} 是第一列的值,每个后面的值是第二列的值。对于我们的示例,类似于:

A    a1 
A    b1 
A    c1 
B    a2 
B    b2 
B    c2 

我们在列表 [A,B,...] 中包含所有第一列标签。

我尝试 df.apply 一些功能,在我看来这似乎一点也不可怕,更像是机器级代码。有人有想法吗?

请您参考如下方法:

这是一种替代方法,它依赖于标签列表中的成员资格,而不是字符串解析:

In [78]: labels = ["A", "B"] 
 
In [79]: marks = s.isin(labels) 
 
In [80]: pd.concat([s.where(marks).ffill(), s], axis=1).loc[~marks] 
Out[80]:  
   0   1 
1  A  a1 
2  A  b1 
3  A  c1 
5  B  a2 
6  B  b2 
7  B  c2 

一步一步,首先我们构建marks,这是一个 bool 系列,告诉我们每个新部分从哪里开始:

In [22]: marks = s.isin(labels) 
 
In [23]: marks 
Out[23]:  
0     True 
1    False 
2    False 
3    False 
4     True 
5    False 
6    False 
7    False 
dtype: bool 

最初我打算使用 marks.cumsum() 进行分组,但在这里使用 where 更简单。

然后我们可以使用 s.where(marks).ffill() 获得包含适当标签的系列:

In [24]: s.where(marks) 
Out[24]:  
0      A 
1    NaN 
2    NaN 
3    NaN 
4      B 
5    NaN 
6    NaN 
7    NaN 
dtype: object 
 
In [25]: s.where(marks).ffill() 
Out[25]:  
0    A 
1    A 
2    A 
3    A 
4    B 
5    B 
6    B 
7    B 
dtype: object 

之后,我们只是连接:

In [26]: pd.concat([s.where(marks).ffill(), s], axis=1) 
Out[26]:  
   0   1 
0  A   A 
1  A  a1 
2  A  b1 
3  A  c1 
4  B   B 
5  B  a2 
6  B  b2 
7  B  c2 

并使用 .loc[~marks] 保留不标记新部分开始的行:

In [27]: pd.concat([s.where(marks).ffill(), s], axis=1).loc[~marks] 
Out[27]:  
   0   1 
1  A  a1 
2  A  b1 
3  A  c1 
5  B  a2 
6  B  b2 
7  B  c2