设置多索引Pandas DataFrame的特定单元格

时间:2016-07-26 23:44:21

标签: python pandas dataframe

我有一个DataFrame(df_test),其中包含行标签('字母')和列名称('数字'),可以按行标签进行分组。

>>> letters = ['a','a','a','a','a','b','b','b','c','c','c','c']
>>> n = {'numbers': [0,1,2,3,4,0,1,2,0,1,2,3]}

>>> df_test = pd.DataFrame(n, index=letters)
>>> print df_test

       numbers        
a      0
a      1
a      2
a      3
a      4
b      0
b      1
b      2
c      0
c      1
c      2
c      3

我想创建一个名为' Position'的新列。每组的第一行(即组a,组b,组c)应该是' S'最后一行应该是' E'并且插入的行应该是' 39; M&#39 ;. (对于开始,中间和结束。;))它看起来像这样:

       numbers    Position
a      0          S
a      1          M
a      2          M
a      3          M
a      4          E
b      0          S
b      1          M
b      2          E
c      0          S
c      1          M
c      2          M
c      3          E

我尝试使用.loc和.iloc的组合将新值分配给正确的单元格但收到错误消息。

>>> df_test['Position'] = 'M'
>>> for idxName,frame in df_test.groupby(level=0):
        df_test.loc[idxName,('Position')].iloc[0] = 'S'
        df_test.loc[idxName,('Position')].iloc[-1] = 'E'

__main__:2: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
__main__:3: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

我想这个问题来自于在使用.loc []之后尝试使用.iloc []但是我不太了解Pandas以获得不同的解决方案并且尽管在网上找不到任何东西几小时的搜索。任何帮助(a)理解我收到警告的原因和(b)将我的细胞设置为正确的值将非常感激!

2 个答案:

答案 0 :(得分:0)

使用apply

groupby写一个函数
def first_last_me(df, c='Position'):
    df[c] = 'M'
    df.iloc[0, -1] = 'S'
    df.iloc[-1, -1] = 'E'
    return df

df_test.groupby(level=0).apply(first_last_me)

enter image description here

答案 1 :(得分:0)

因为@ piRSquared的回答并不适用于我的DataFrame,原因还不得而知,这就是我最终的目标。

>>> letters = ['a','a','a','a','a','b','b','b','c','c','c','c']
>>> n = {'numbers': [0,1,2,3,4,0,1,2,0,1,2,3]}
>>> df_test = pd.DataFrame(n, index=letters)
>>> df_test['Position'] = 'M'

>>> df_test2 = pd.DataFrame()

>>> for idxName,frame in df_test.groupby(level=0):
        frameLen = len(df_test.ix[idxName])
        df_s = df_test.ix[idxName].iloc[0:1].copy()
        df_e = df_test.ix[idxName].iloc[-1:frameLen].copy()
        df_s['Position'] = 'S'
        df_e['Position'] = 'E'
        df_test2 = df_test2.append([df_s,df_test.loc[idxName].ix[1:-1],df_e],ignore_index=False)

>>> df_test2
     numbers Position
a    0        S
a    1        M
a    2        M
a    3        M
a    4        E
b    0        S
b    1        M
b    2        E
c    0        S
c    1        M
c    2        M
c    3        E

我会尝试使用' apply'来弄清楚如何做到这一点。如果可能的话,但现在这个黑客行之有效。