python - 将多个值拆分为新行
问题描述
我有一个数据框,其中几列可能在单个观察中具有多个值。这些行中的每个观察在观察的末尾都有一个“/”,无论是否有多个。这意味着一些值看起来像这样:'OneThing/' 而另一些像这样:'OneThing/AnotherThing/'
我需要在观察中获取多个值的值并将它们拆分为单独的行。
这是数据框之前的一般示例:
ID Date Name ColA ColB Col_of_Int ColC ColD
1 09/12 Ann String String OneThing/ String String
2 09/13 Pete String String OneThing/AnotherThing String String
3 09/13 Ann String String OneThing/AnotherThing/ThirdThing/ String String
4 09/12 Pete String String OneThing/ String String
我想要的输出是:
ID Date Name ColA ColB Col_of_Int ColC ColD
1 09/12 Ann String String OneThing String String
2 09/13 Pete String String OneThing String String
2 09/13 Pete String String Another Thing String String
3 09/13 Ann String String OneThing String String
3 09/13 Ann String String AnotherThing String String
3 09/13 Ann String String ThirdThing String String
4 09/12 Pete String String OneThing/ String String
我尝试了以下方法:
df = df[df['Column1'].str.contains('/')]
df_split = df[df['Column1'].str.contains('/')]
df1 = df_split.copy()
df2 = df_split.copy()
split_cols = ['Column1']
for c in split_cols:
df1[c] = df1[c].apply(lambda x: x.split('/')[0])
df2[c] = df2[c].apply(lambda x: x.split('/')[1])
new_rows = df1.append(df2)
df.drop(df_split.index, inplace=True)
df = df.append(new_rows, ignore_index=True)
这可行,但我认为它在每个“/”之后创建新行,这意味着为每个观察创建一个新行,只有一个值(我想要零个新行),并且正在创建两个新行每个观察值都有两个值(只需要一个),等等。
当观察中有三个或更多值时,这尤其令人沮丧,因为我得到了几个不必要的行。
有什么办法可以解决这个问题,以便只有一个以上的观察被添加到新行中?
解决方案
如果您使用df['column_of_interest'] = df['column_of_interest'].str.rstrip('/')
,您的方法会起作用(我认为),因为它会/
在您的观察结束时消除这种烦人的情况。但是,循环是无效的,并且您拥有它的方式要求您知道在您的列中最多有多少观察值。这是另一种方式,我认为可以满足您的需求:
举个例子df
:
df = pd.DataFrame({'column_of_interest':['onething/',
'onething/twothings/',
'onething/twothings/threethings/'],
'values1': [1,2,3],
'values2': [5,6,7]})
>>> df
column_of_interest values1 values2
0 onething/ 1 5
1 onething/twothings/ 2 6
2 onething/twothings/threethings/ 3 7
这有点混乱,因为您想大概保留列中的数据之外column_of_interest
。因此,您可以使用以下方法临时找到它们并将它们放在一边:
value_columns = [i for i in df.columns if i != 'column_of_interest']
并将它们放入索引中以进行以下操作(最后恢复它们):
new_df = (df.set_index(value_columns)
.column_of_interest.str.rstrip('/')
.str.split('/')
.apply(pd.Series)
.stack()
.rename('new_column_of_interest')
.reset_index(value_columns))
你的new_df
then 看起来像:
>>> new_df
values1 values2 new_column_of_interest
0 1 5 onething
0 2 6 onething
1 2 6 twothings
0 3 7 onething
1 3 7 twothings
2 3 7 threethings
或者,使用merge
:
new_df = (df[value_columns].merge(df.column_of_interest
.str.rstrip('/')
.str.split('/')
.apply(pd.Series)
.stack()
.reset_index(1, drop=True)
.to_frame('new_column_of_interest'),
left_index=True, right_index=True))
编辑:在您发布的数据框上,这会导致:
ID Date Name ColA ColB ColC ColD new_column_of_interest
0 1 09/12 Ann String String String String OneThing
0 2 09/13 Pete String String String String OneThing
1 2 09/13 Pete String String String String AnotherThing
0 3 09/13 Ann String String String String OneThing
1 3 09/13 Ann String String String String AnotherThing
2 3 09/13 Ann String String String String ThirdThing
0 4 09/12 Pete String String String String OneThing
推荐阅读
- swift - 混淆地图与平面地图:无法使用类型为“(()-> EventLoopFuture)”的参数列表调用“平面地图”
- java - 从向下滚动菜单中选择。写至少 1 个字符,等待可见,然后按 enter 或单击
- cron - Google MCF API - 10:00UTC+2 后获取数据
- python - 打开文件而不考虑他的扩展名
- node.js - 尝试安装 Angular CLI 时出现 NPM 错误
- python - 从简历创建页面列表并获取第一页
- java - 如何使用 Springboot 分别访问作为 Mono 对象返回的属性
- angular - 在 Angular 8 中,上传时由于 polyfills-es2015 发生构建错误
- angular - 在角度(单元测试)中有没有办法通过其 @Input() 属性值来查找组件?
- java - 为什么 request.getParamether 在 jsp 中不起作用