Pandas数据框的操作与绘图

4 投票
1 回答
1395 浏览
提问于 2025-04-18 05:52

我正在使用WinPython 3.4和matplotlib 1.3.1,从mysql数据库中提取数据,生成一个数据框(dataframe)。我从查询中得到的原始数据框看起来是这样的:

            wafer_number test_type  test_pass  x_coord  y_coord  test_el_id wavelength intensity
        0       HT2731      T2          1       38       54          24      288.68   4413
        1       HT2731      T2          1       40       54          25      257.42   2595
        2       HT2731      T2          1       50       54          28      300.00   2836
        3       HT2731      T2          1       52       54          29      300.00   2862
        4       HT2731      T2          1       54       54          30      300.00   3145
        5       HT2731      T2          1       56       54          31      300.00   2804
        6       HT2731      T2          1       58       54          32      255.69   2803
        7       HT2731      T2          1       59       54          33      257.23   2991
        8       HT2731      T2          1       60       54          34      262.45   3946
        9       HT2731      T2          1       62       54          35      291.84   9398
        10      HT2801      T2          1       38       55          54      288.68   4125
        11      HT2801      T2          1       38       56          55      265.25   4258

我想要的是在图表中把波长(wavelength)放在x轴上,把强度(intensity)放在y轴上,并且每个不同的晶圆编号(wafer number)作为一个独立的系列。我需要保留x_coord和y_coord这两个变量,以便我可以在后面识别出特别的数据点,理想情况下是通过点击它们并将其添加到一个列表中。等我把这些东西画出来后,我会再处理这个。

我认为使用内置的数据框绘图功能需要我对数据框执行一个pivot_table的方法,

wl_vs_int = results.pivot_table(values='intensity', rows=['x_coord', 'y_coord','wavelength'], cols='wafer_number')

这样就能把数据框变成:

        wafer_number    HT2478  HT2625  HT2644  HT2671  HT2673  HT2719  HT2731  HT2796  HT2801
 x_coord  y_coord   wavelength                                  
    27      35  289.07   NaN     NaN     NaN     5137    NaN     NaN     NaN     NaN     NaN
            36  250.88   4585    NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN
            37  260.90   NaN     NaN     NaN     NaN     4270    NaN     NaN     NaN     NaN
            38  288.87   NaN     NaN     NaN     8191    NaN     NaN     NaN     NaN     NaN
            40  259.74   NaN     NaN     NaN     NaN     17027   NaN     NaN     NaN     NaN
            41  259.74   NaN     NaN     NaN     NaN     18742   NaN     NaN     NaN     NaN
            42  259.74   NaN     NaN     NaN     NaN     34098   NaN     NaN     NaN     NaN
    28      34  268.27   NaN     NaN     NaN     NaN     2080    NaN     NaN     NaN     NaN
            38  257.42   7727    NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN
            44  260.13   NaN     NaN     NaN     NaN     55329   NaN     NaN     NaN     NaN

但现在索引变成了一个多重索引,包括x、y坐标和波长,所以当我尝试打印波长和列的时候,

plt.scatter(wl_vs_int.wavelength, wl_vs_int.columns)

我遇到了AttributeError错误:

AttributeError: 'DataFrame' object has no attribute 'wavelength'

我尝试将数据框重新索引回默认索引,但仍然得到“'DataFrame'对象没有'wavelength'属性”的结果。

一定有更好的方法来重新排列数据框,以便通过内置的数据框绘图功能实现这一点,或者只绘制某些列与其他列(这些列是动态的)。我显然是python和pandas的新手,但我花了好几天时间尝试用不同的方法来实现这一点,却没有结果。任何帮助都会非常感谢。谢谢。

1 个回答

3

要在图表上把波长放在横轴(x轴),把强度放在纵轴(y轴),并且让每个不同的晶圆编号显示成自己的系列,你可以根据 wafer_number 来把数据分组,然后分别处理每一组数据。

import pandas as pd
from StringIO import StringIO
import matplotlib.pyplot as plt

data = \
"""wafer_number,test_type,test_pass,x_coord,y_coord,test_el_id,wavelength,intensity
HT2731,T2,1,38,54,24,288.68,4413
HT2731,T2,1,40,54,25,257.42,2595
HT2731,T2,1,50,54,28,300.00,2836
HT2731,T2,1,52,54,29,300.00,2862
HT2731,T2,1,54,54,30,300.00,3145
HT2731,T2,1,56,54,31,300.00,2804
HT2731,T2,1,58,54,32,255.69,2803
HT2731,T2,1,59,54,33,257.23,2991
HT2731,T2,1,60,54,34,262.45,3946
HT2731,T2,1,62,54,35,291.84,9398
HT2801,T2,1,38,55,54,288.68,4125
HT2801,T2,1,38,56,55,265.25,4258"""

df = pd.read_csv(StringIO(data),sep = ',')
dfg = df.groupby('wafer_number')

colors = 'bgrcmyk'
fig, ax = plt.subplots()
for i,k in enumerate(dfg.groups.keys()):
    currentGroup = df.loc[dfg.groups[k]]
    color = colors[i % len(colors)]
    ax.plot(currentGroup['wavelength'].values,currentGroup['intensity'].values,\
            ls='', color = color, label = k, marker = 'o', markersize = 8)
legend = ax.legend(loc='upper center', shadow=True)
plt.xlabel('wavelength')
plt.ylabel('intensity')
plt.show()

撰写回答