Python:根据特定值将列拆分为串联的行
Posted
技术标签:
【中文标题】Python:根据特定值将列拆分为串联的行【英文标题】:Python: Splitting a Column into concatenated rows based on specific Values 【发布时间】:2022-01-24 04:59:16 【问题描述】:我确信以前有人问过这样的问题,但我目前的搜索尝试没有找到解决方案。
我有一列文本值,例如:
import pandas as pd
df2 = pd.DataFrame('text':['a','bb','cc','4','m','...'])
print(df2)
text
0 a
1 bb
2 cc
3 4
4 m
5 ...
'text' 中的列由字符串、整数、浮点数和 nan 类型的数据组成。
我正在尝试合并(每个文本值之间有一个空格 [''])所有文本值中间文本列中的每个数字(int/float),忽略 Nan 值,使每个连接集成为单独的行。
最有效的方法是什么?
我想可能将所有值读入一个字符串,去掉 Nan,如果遇到一个数字,然后连续拆分,但这似乎效率很低。
感谢您的帮助!
编辑:
期望的样本输出
text
0 'a bb cc'
1 'm ...'
【问题讨论】:
你能提供一个示例输出吗? 更新了所需的样本输出 你想对列中的数字做什么? 这个操作看起来不太适合 pandas。它本质上是顺序的。作为旁注,你可以有两个连续的数字吗?如果是这样,预期的输出是什么?另外,这些数字是等间隔的吗? 数字可以删除,我不需要它们。这些数字在整个数据中的间距不相等。数字之间的文本值实际上是句子。 【参考方案1】:我会完全避免使用 pandas 进行此操作。相反,使用库模块more_itertools
- 即split_at()
函数:
import more_itertools as mit
def test(x): # Test if X is a number of some sort or a nan
try: float(x); return True
except: return False
result = [" ".join(x) for x in mit.split_at(df2['text'].dropna(), test)]
# ['a bb cc', 'm ...']
df3 = pd.DataFrame(result, columns=['text',])
附:在平均组长度为 10 的 13,000 行数据帧上,该解决方案比 jezrael 提出的 pandas 解决方案快 2 倍(0.00087 秒对 0.00156 秒)。确实,差别不大。
【讨论】:
这给了我 AttributeError: 'int' object has no attribute 'isdigit' 上次编辑之后尝试过解决方案吗? 所以,这似乎现在运行没有错误(给出与 Jezrael 的解决方案相同的文本结果),但在输出数据框中似乎有很大的空格(例如,索引 2-8 是空白和数据框中的索引 1 和 9 中有文本) 我添加了一个功能,可以删除那些空格,还解决了@jezrael 对 nans 的担忧。 据我了解,您添加的功能是 .dropna()。这纠正了大多数空白的问题,但那里仍然有一组空白。我检查了类型,它们似乎是字符串类型。所以我猜这意味着这些是“”字符串?【参考方案2】:您可以将列转换为数字并测试非缺失值,因此为数字行获取True
s,然后在DataFrame.loc
中通过~
仅过滤倒置掩码中的非数字,并通过累积总和通过@ 掩码聚合987654322@ 与聚合 join
:
#for remove NaNs before solution
df2 = df2.dropna(subset=['text'])
m = pd.to_numeric(df2['text'], errors='coerce').notna()
df = df2.loc[~m, 'text'].groupby(m.cumsum()).agg(' '.join).reset_index(drop=True).to_frame()
print (df)
text
0 a bb cc
1 m ...
【讨论】:
不错的答案。 +1以上是关于Python:根据特定值将列拆分为串联的行的主要内容,如果未能解决你的问题,请参考以下文章