熊猫:如何将列中的文本分割成多行?

熊猫:如何将列中的文本分割成多行?

我正在处理一个大型CSV文件,最后一列的旁边有一个文本字符串,我想用一个特定的分隔符来分割。我想知道是否有一种使用熊猫或蟒蛇的简单方法?

CustNum  CustomerName     ItemQty  Item   Seatblocks                 ItemExt32363    McCartney, Paul     
 3     F04    2:218:10:4,6                   6031316    Lennon, John        25     F01   
  1:13:36:1,12 1:13:37:1,13     300

我想分道扬镳(' ')然后是结肠(':')Seatblocks列,但每个单元格将导致不同的列数。我有一个函数来重新排列,所以Seatblocks列在纸的末尾,但我不知道该怎么做。我可以在excel中使用内置的text-to-columns函数和快速宏,但是我的数据集有太多的记录需要Excel处理。

最后,我想记录下约翰列侬的记录,并创建多行,每一组座位的信息都在一条单独的线路上。


慕娘9325324
浏览 531回答 3
3回答

明月笑刀无情

这将SeatBlock按空间划分,并给出各自的行。In [43]: dfOut[43]:    CustNum     CustomerName  ItemQty Item                 Seatblocks  ItemExt0    32363  McCartney, Paul        3  F04               2:218:10:4,6       601    31316     Lennon, John       25  F01  1:13:36:1,12 1:13:37:1,13      300In [44]: s = df['Seatblocks'].str.split(' ').apply(Series, 1).stack()In [45]: s.index = s.index.droplevel(-1) # to line up with df's indexIn [46]: s.name = 'Seatblocks' # needs a name to joinIn [47]: sOut[47]: 0    2:218:10:4,61    1:13:36:1,121    1:13:37:1,13Name: Seatblocks, dtype: objectIn [48]: del df['Seatblocks']In [49]: df.join(s)Out[49]:    CustNum     CustomerName  ItemQty Item  ItemExt    Seatblocks0    32363  McCartney, Paul        3  F04       60  2:218:10:4,61    31316     Lennon, John       25  F01      300  1:13:36:1,121    31316     Lennon, John       25  F01      300  1:13:37:1,13或者,在它自己的列中给每个冒号分隔的字符串:In [50]: df.join(s.apply(lambda x: Series(x.split(':'))))Out[50]:    CustNum     CustomerName  ItemQty Item  ItemExt  0    1   2     30    32363  McCartney, Paul        3  F04       60  2  218  10   4,61    31316     Lennon, John       25  F01      300  1   13  36  1,121    31316     Lennon, John       25  F01      300  1   13  37  1,13这有点难看,但也许有人会提出一个更漂亮的解决方案。

神不在的星期二

不同于丹,我认为他的回答很优雅.但不幸的是,这也是非常低效的。所以,既然刚才提到的问题“大CSV文件”,让我建议试试壳牌丹的解决方案:time python -c "import pandas as pd; df = pd.DataFrame(['a b c']*100000, columns=['col']); print df['col'].apply(lambda x : pd.Series(x.split(' '))).head()"..与这一备选方案相比:time python -c "import pandas as pd; from scipy import array, concatenate; df = pd.DataFrame(['a b c']*100000, columns=['col']); print pd.DataFrame(concatenate(df['col'].apply( lambda x : [x.split(' ')]))).head()"..这是:time python -c "import pandas as pd; df = pd.DataFrame(['a b c']*100000, columns=['col']); print pd.DataFrame(dict(zip(range(3), [df['col'].apply(lambda x : x.split(' ')[i]) for i in range(3)]))).head()"第二个简单地避免分配100000系列,这足以使它大约快10倍。但是第三种解决方案(具有讽刺意味的是,它浪费了很多对str.split()的调用)(每行每列调用一次,因此比其他两种解决方案多三倍)。40次比第一个更快,因为它甚至避免了10万个列表的实例。是的,确实有点丑.编辑: 这个答案建议如何使用“to_list()”并避免使用lambda。结果就像time python -c "import pandas as pd; df = pd.DataFrame(['a b c']*100000, columns=['col']); print pd.DataFrame(df.col.str.split().tolist()).head()"这甚至比第三种解决方案更有效,当然也更优雅。编辑:更简单time python -c "import pandas as pd; df = pd.DataFrame(['a b c']*100000, columns=['col']); print pd.DataFrame(list(df.col.str.split())).head()"也起作用,而且是差不多了很有效率。编辑: 更简单!并处理NAN(但效率较低):time python -c "import pandas as pd; df = pd.DataFrame(['a b c']*100000, columns=['col']); print df.col.str.split(expand=True).head()"

繁星点点滴滴

import pandas as pdimport numpy as npdf = pd.DataFrame({'ItemQty': {0: 3, 1: 25},                    'Seatblocks': {0: '2:218:10:4,6', 1: '1:13:36:1,12 1:13:37:1,13'},                    'ItemExt': {0: 60, 1: 300},                    'CustomerName': {0: 'McCartney, Paul', 1: 'Lennon, John'},                    'CustNum': {0: 32363, 1: 31316},                    'Item': {0: 'F04', 1: 'F01'}},                     columns=['CustNum','CustomerName','ItemQty','Item','Seatblocks','ItemExt'])print (df)   CustNum     CustomerName  ItemQty Item                 Seatblocks  ItemExt0    32363  McCartney, Paul        3  F04               2:218:10:4,6       601    31316     Lennon, John       25  F01  1:13:36:1,12 1:13:37:1,13      300另一种类似的链接解决方案是使用reset_index和rename:print (df.drop('Seatblocks', axis=1)             .join             (             df.Seatblocks             .str             .split(expand=True)             .stack()             .reset_index(drop=True, level=1)             .rename('Seatblocks')                        ))   CustNum     CustomerName  ItemQty Item  ItemExt    Seatblocks0    32363  McCartney, Paul        3  F04       60  2:218:10:4,61    31316     Lennon, John       25  F01      300  1:13:36:1,121    31316     Lennon, John       25  F01      300  1:13:37:1,13如果在列中是不 NaN值,最快的解决方案是使用list理解力DataFrame构造者:df = pd.DataFrame(['a b c']*100000, columns=['col'])In [141]: %timeit (pd.DataFrame(dict(zip(range(3), [df['col'].apply(lambda x : x.split(' ')[i]) for i in range(3)]))))1 loop, best of 3: 211 ms per loopIn [142]: %timeit (pd.DataFrame(df.col.str.split().tolist()))10 loops, best of 3: 87.8 ms per loopIn [143]: %timeit (pd.DataFrame(list(df.col.str.split())))10 loops, best of 3: 86.1 ms per loopIn [144]: %timeit (df.col.str.split(expand=True))10 loops, best of 3: 156 ms per loopIn [145]: %timeit (pd.DataFrame([ x.split() for x in df['col'].tolist()]))10 loops, best of 3: 54.1 ms per loop但是如果列包含NaN只起作用str.split带参数expand=True哪一回DataFrame (文献资料),它解释了为什么它更慢:df = pd.DataFrame(['a b c']*10, columns=['col'])df.loc[0] = np.nanprint (df.head())     col0    NaN1  a b c2  a b c3  a b c4  a b cprint (df.col.str.split(expand=True))     0     1     20  NaN  None  None1    a     b     c2    a     b     c3    a     b     c4    a     b     c5    a     b     c6    a     b     c7    a     b     c8    a     b     c9    a     b     c
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python