我有一个 pandas dataframe
,其中一列文本字符串包含逗号分隔值 . 我想拆分每个CSV字段并为每个条目创建一个新行(假设CSV是干净的,只需要在','上拆分) . 例如, a
应该变为 b
:
In [7]: a
Out[7]:
var1 var2
0 a,b,c 1
1 d,e,f 2
In [8]: b
Out[8]:
var1 var2
0 a 1
1 b 1
2 c 1
3 d 2
4 e 2
5 f 2
到目前为止,我已经尝试了各种简单的函数,但 .apply
方法在轴上使用时似乎只接受一行作为返回值,而且我无法使用 .transform
. 我们欢迎所有的建议!
示例数据:
from pandas import DataFrame
import numpy as np
a = DataFrame([{'var1': 'a,b,c', 'var2': 1},
{'var1': 'd,e,f', 'var2': 2}])
b = DataFrame([{'var1': 'a', 'var2': 1},
{'var1': 'b', 'var2': 1},
{'var1': 'c', 'var2': 1},
{'var1': 'd', 'var2': 2},
{'var1': 'e', 'var2': 2},
{'var1': 'f', 'var2': 2}])
我知道这不起作用,因为我们通过numpy丢失DataFrame元数据,但它应该让你了解我尝试做的事情:
def fun(row):
letters = row['var1']
letters = letters.split(',')
out = np.array([row] * len(letters))
out['var1'] = letters
a['idx'] = range(a.shape[0])
z = a.groupby('idx')
z.transform(fun)
14 回答
这样的事情怎么样:
然后你只需要重命名列
经过痛苦的实验,找到比接受的答案更快的东西,我得到了这个工作 . 它在我试用的数据集上运行速度快了大约100倍 .
如果有人知道如何使这更优雅,请务必修改我的代码 . 我找不到一种方法可以在没有设置你想要保留的其他列作为索引,然后重置索引并重新命名列,但我想象还有其他的东西可行 .
UPDATE2: 更通用的矢量化函数,适用于多个
normal
和多个list
列演示:
多个
list
列 - 所有list
列必须在每行中具有相同的元素数:Build :
CSV列:
使用这个小技巧,我们可以将类似CSV的列转换为
list
列:UPDATE: generic vectorized approach (will work also for multiple columns):
原DF:
Solution:
首先让我们将CSV字符串转换为列表:
现在我们可以这样做:
OLD answer:
受到@AFinkelstein solution的启发,我想让它更加通用化,可以应用于具有两列以上的DF,并且与AFinkelstein的解决方案一样快,几乎一样快:
对于这个常见任务,这是一个function I wrote . 它比
Series
/stack
方法更有效 . 列顺序和名称将保留 .使用此功能,original question非常简单:
像类似的问题:pandas: How do I split text in a column into multiple rows?
你可以这样做:
我想出了一个具有任意数量列的数据帧的解决方案(同时仍然只分离一列的条目) .
这是一条相当简单的消息,它使用pandas
str
accessor中的split
方法,然后使用NumPy将每一行展平为一个数组 .通过使用
np.repeat
重复非拆分列正确的次数来检索相应的值 .TL; DR
示范
让我们创建一个包含列表的新数据框
d
一般评论
我将
np.arange
与repeat
一起使用来生成我可以与iloc
一起使用的数据帧索引位置 .常见问题
为什么我不使用loc?
因为索引可能不是唯一的,并且使用
loc
将返回与查询索引匹配的每一行 .为什么不使用values属性和slice?
当调用
values
时,如果整个数据帧在一个内聚"block"中,Pandas将返回一个数组的视图"block" . 否则,熊猫将不得不拼凑一个新阵列 . 在cobbling时,该数组必须是统一的dtype . 通常这意味着返回一个dtype为object
的数组 . 通过使用iloc
而不是切割values
属性,我减轻了自己不必处理的问题 .为什么使用assign?
当我使用
assign
使用我正在爆炸的相同列名时,我会覆盖现有列并保持其在数据框中的位置 .为什么索引值重复?
通过在重复位置上使用
iloc
,结果索引显示相同的重复模式 . 列表或字符串的每个元素重复一次 .这可以通过
reset_index(drop=True)
重置For Strings
我不想过早地拆分弦乐 . 因此,我计算
sep
参数的出现,假设如果我要拆分,结果列表的长度将比分隔符的数量多一个 .然后我使用
sep
到join
字符串然后split
.列表
与字符串类似,但我不需要计算
sep
的出现次数,因为它已经分裂了 .我使用Numpy的
concatenate
将列表混在一起 .基于优秀的@ DMulligan的solution,这里是一个通用的矢量化(无循环)函数,它将数据帧的一列拆分成多行,并将其合并回原始数据帧 . 它还使用了一个很棒的通用
change_column_order
函数answer .例:
请注意,它会保留原始索引和列的顺序 . 它也适用于具有非顺序索引的数据帧 .
刚从上面使用了jiln的优秀答案,但需要扩展以分割多个列 . 以为我会分享 .
字符串函数split可以选择boolean参数'expand' .
以下是使用此参数的解决方案:
我已经提出了以下解决这个问题的方法:
另一个使用python copy包的解决方案
有可能在不改变数据帧结构的情况下拆分和分解数据帧
输入:
日期: