Python 将多个值拆分为新行
我有一个数据框,其中几列可能在一个观察中有多个值。这些行中的每个观测值在观测结束时都有一个“/”,无论是否有多个观测值。这意味着一些值如下所示:“OneThing/”而其他值如下所示:“OneThing/AnotherThing/” 我需要在一个观测值中有多个值的地方获取这些值,并将它们分割成单独的行 这是dataframe之前的一般示例:Python 将多个值拆分为新行,python,python-3.x,pandas,split,append,Python,Python 3.x,Pandas,Split,Append,我有一个数据框,其中几列可能在一个观察中有多个值。这些行中的每个观测值在观测结束时都有一个“/”,无论是否有多个观测值。这意味着一些值如下所示:“OneThing/”而其他值如下所示:“OneThing/AnotherThing/” 我需要在一个观测值中有多个值的地方获取这些值,并将它们分割成单独的行 这是dataframe之前的一般示例: ID Date Name ColA ColB Col_of_Int ColC ColD 1
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\u of u interest']=df['column\u of u 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
这有点混乱,因为您可能希望将列中的数据保留在感兴趣的列之外。因此,您可以使用以下方法临时查找这些内容并将其丢弃:
value_columns = [i for i in df.columns if i != 'column_of_interest']
并将它们放在索引中,以便进行以下操作(最后将其还原):
然后你的新的_df
看起来像:
>>> 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
或者,使用合并:
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
如果上面添加了df=pd.DataFrame({'Column1':['OneThing/','twoothing/AnotherThing/']})
?@Ben.T,您能给出预期的输出吗!这个效果好多了!我仍然得到了额外的专栏,但我相信我可以放弃。哦,我的糟糕。我是说多排一排。每行有一份副本。这意味着数据框中的每一行与上面的行相同,但复制的行中的相关列为空。这有意义吗?我想我明白你说的,但是当我运行它时,我也不会得到额外的一行(见上面编辑中的输出)。你得到的是我想要的,但我得到的是不同的东西。添加到上面,但可能需要几分钟,因为它需要同行评审。抱歉!新来的。我不明白它们为什么不同,但我得到的结果与您在删除带有空值的行时得到的结果相同。
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