首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按数据中列的相似值分组

按数据中列的相似值分组
EN

Stack Overflow用户
提问于 2022-08-26 20:57:56
回答 1查看 84关注 0票数 0

我使用的是一个包含岩石和土壤样本数据的DataFrame。我想创建两个单独的地块,一个用于岩石,另一个用于土壤,显示SO3相对于SIO2的组成。我只创建了一本岩石字典,但仍然有90+示例。如图所示,有些人有相似的名字。例如,“Adirondack”出现了3次。我可以手动检查所有这些语句,但这需要一段时间(P.S.我已经完成了,但是我仍然想知道比if ... elif ...语句更简单的方法,因为我必须手动创建一个图例条目以避免许多重复的条目)。

例如,我如何将具有相同x字母的字母组合在一起,并将它们保存在一个新的dataframe或我的字典中,如'Adirondack (all)‘(可能在'_’之前取名称的一部分,这样它就会以这种方式出现在图例中),并将'Adirondack_‘等的三组值保存在一个字典条目中。

代码语言:javascript
复制
Rocks = APXSData[APXSData.Type.str.contains('R')]
RockLabels = Rocks['Sample'].to_list()
RockDict = {}

for i in RockLabels:
    SiO2val = np.extract(Rocks["Sample"]==i, Rocks["SiO2"])
    SO3val = np.extract(Rocks["Sample"]==i, Rocks["SO3"])
    newKey = i  
    RockDict[newKey] = {'SiO2':SiO2val, 'SO3':SO3val}

DatabyRockSample = pd.DataFrame(RockDict)

fig = plt.figure() 

for i in RockLabels:
    plt.scatter(
        DatabyRockSample[i]["SiO2"],
        DatabyRockSample[i]["SO3"], 
        marker='o', 
        label = i)    #, color = colors[count], edgecolors = edgecolor[count], 

plt.xlabel("SiO$_2$", labelpad = 10)
plt.ylabel("SO$_3$", labelpad = 10)
plt.title('Composition of all rocks \n at Gusev Crater')
plt.legend()
EN

回答 1

Stack Overflow用户

发布于 2022-08-27 18:37:29

让我们准备一些虚拟数据:

代码语言:javascript
复制
df = pd.DataFrame({
    'Sol': [14,18,33,34,41],
    'Type': ['SU','RU','RB','RR','SU'],
    'Sample': ['Gusev_Soil','Adirondack_asis','Adirondack_brush','Adirondack_RAT','Gusev_Other'],
    'N': [45,126,129,128,76],
    'Na2O': [2.8,2.3,2.8,2.4,2.7],
    # ...
})

以下是我们的数据框架:

代码语言:javascript
复制
   Sol Type            Sample    N  Na2O
0   14   SU        Gusev_Soil   45   2.8
1   18   RU   Adirondack_asis  126   2.3
2   33   RB  Adirondack_brush  129   2.8
3   34   RR    Adirondack_RAT  128   2.4
4   41   SU       Gusev_Other   76   2.7

我们可以用这种方式分组。

如果我们唯一的选择是匹配前n个字母,那么:

代码语言:javascript
复制
n = 5   
grouper = df['Sample'].str[:n]
groups = {name: group for name, group in df.groupby(grouper)}

如果我们可以通过分割提取有意义的数据,我认为这更好,那么:

代码语言:javascript
复制
# in this case we can split by '_' and get the first word
grouper = df['Sample'].str.split('_').str.get(0)   
groups = {name: group for name, group in df.groupby(grouper)}

如果拆分不是那么简单,假设我们的单词由空格、下划线或连字符分隔,那么我们可以使用str.extract方法:

代码语言:javascript
复制
grouper = df['Sample'].str.extract('\A(.*)(?=[ _-])')
groups = {name: group for name, group in df.groupby(grouper)}

我们也可以避免创建字典。让我们看看如何迭代通过拆分获得的组,作为一个例子:

代码语言:javascript
复制
grouper = df['Sample'].str.split('_').str.get(0)
groups = df.groupby(grouper)
for name, dataframe in groups:
    print(f'name: {name}')
    print(dataframe, '\n')

输出:

代码语言:javascript
复制
name: Adirondack
   Sol Type            Sample    N  Na2O
1   18   RU   Adirondack_asis  126   2.3
2   33   RB  Adirondack_brush  129   2.8
3   34   RR    Adirondack_RAT  128   2.4 

name: Gusev
   Sol Type       Sample   N  Na2O
0   14   SU   Gusev_Soil  45   2.8
4   41   SU  Gusev_Other  76   2.7 

石头也是一样。我想我们可以比APXSData.Type.str.contains('R')做得更好

代码语言:javascript
复制
APXSData['Type'].str[0] == 'R'
APXSData['Type'].str.startswith('R')

让我们将岩石分开,并按它们的主要名称分组:

代码语言:javascript
复制
is_rock = df['Type'].str.startswith('R')
grouper = df['Sample'].str.split('_').str.get(0)
groups_of_rocks = df[is_rock].groupby(grouper)

for k,v in groups_of_rocks:
    print(k)
    print(v)

输出:

代码语言:javascript
复制
Adirondack
   Sol Type            Sample    N  Na2O
1   18   RU   Adirondack_asis  126   2.3
2   33   RB  Adirondack_brush  129   2.8
3   34   RR    Adirondack_RAT  128   2.4

为了只为某一组感兴趣的人绘制数据,我们可以使用get_group(name)

代码语言:javascript
复制
groups.get_group('Adirondack').plot.bar(x='Sample', y=['N','Na2O'])

另请参阅:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73506404

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档