pandas如何將相同ID的字符串進行合併

寫在前面:說來真的很巧,先是有個人在一個qq比賽羣裏扔了這個問題,我覺得很有意思,然後自己嘗試了下,就將自己寫的一段代碼發給了他。事後,在一個微信公衆號的推文裏,看到這篇文章數據城堡參賽代碼實戰篇(三)—我們來探究一個深奧的問題!裏面給了一些大神對同樣問題的解法,瞬間覺得自己很菜雞,把大神的和自己做個對比,提醒自己對於pandas的使用不能僅僅停留於表面,還有更多優化簡潔的處理方式需要學習!

OUTLINE:

  • 問題描述
  • 自己的解決方案
  • 大神的更優化的解法
  • 總結

問題描述

"""
id   value
1      A
1      B
1      C
2      D
2      E
2      F
變爲:
id  value
1   [A,B,C]
2   [D,E,F]

pandas怎麼把上面的結構變爲下面的形式?
"""

自己的解決方案

import pandas as pd
import numpy as np
data = pd.DataFrame({'id':[1,1,1,2,2,2],'value':['A','B','C','D','E','F']})

data1 = np.array(data.groupby(['id']))#按照id進行分類
# 轉變成array對象之後,可以根據data1[0][1]查看其結構

id_kinds = 2#id的種類,此例比如1、2共兩種
all_value = []
for j in range(2):
    value = []
    for i in data1[j][1]['value']:
        value.append(i)
    all_value.append(value)
print(all_value)

#再創建新的dataframe
new_data = pd.DataFrame({'id':[1,2],'value':all_value})
print(new_data)

輸出結果爲:

   id      value
0   1  [A, B, C]
1   2  [D, E, F]

大神的更優化的解法

解法一:可以用sum方法,將字符串進行連接

import pandas as pd
import numpy as np
data = pd.DataFrame({'id':[1,1,1,2,2,2],'value':['A','B','C','D','E','F']})
data1 = data.groupby(by='id')['value'].sum()

此時的輸出結果爲:

id
1    ABC
2    DEF
Name: value, dtype: object

但是還不是我們想要的,因爲我們還需要在中間加入逗號分隔
① 我們可以先將原始數據的value都變成“,A”

data = pd.DataFrame({'id':[1,1,1,2,2,2],'value':['A','B','C','D','E','F']})
data['value'] = data['value'].apply(lambda x:','+ x)

② 然後,對其使用sum方法進行字符串相加

data1 = data.groupby(by='id').sum()

此時的輸出結果爲,value值之前多了“,”

id  value
1   ,A,B,C
2   ,D,E,F

③ 最後,對該列使用apply函數,去除‘,’

data1['value'] = data1['value'].apply(lambda x :[x[1:]])

就得到了最終的結果:

id  value
1   [A,B,C]
2   [D,E,F]

解法二:對分組之後的結果,直接使用apply函數
一行代碼就搞定!

data1 = data.groupby(by='id').apply(lambda x:[','.join(x['value'])])

那爲什麼可以這麼做呢?
首先需要剖析的是,groupby之後的數據結構是什麼樣的,它是由元組構成的(分組名,數據塊),數據塊也就是dataframe結構。使用以下方式可以查看groupby之後的對象:

for ID,group in group_df:
    print(ID)
    print(group)

apply函數中的x作用的即是數據塊(dataframe),通過數據塊取value那一行得到的是Series對象,於是可以使用join方法進行操作。


總結

  • sum方法不僅可以用於數值計算,還可用於對於一個Series對象而言的字符串相加
a = ['a','b']
c = pd.Series(a).sum()
  • apply函數非常靈活,不僅可以作用於一個Series對象,還可以作用於一個groupby之後的數據塊
data['value'].apply(lambda x :*****)
data.groupby(by='**').apply(lambda x :*****)
  • lambda匿名函數可以極大優化精簡我們的代碼,是一個非常靈活好用的函數,記住它!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章