簡體   English   中英

子集 Pandas DataFrame 二級索引和重新分配值

[英]Subset Pandas DataFrame Secondary Index and Reassigning values

這可能是一個由兩部分組成的問題,但我正在尋找對由其二級索引標識的記錄子集重新縮放(或執行任何操作)的最佳方法。

例如 - 假設我有以下數據框:

>>> df=pd.DataFrame(data=[[1,2,3],[.4,.5,.6],[7,8,9],[.10,.11,.12]], index=pd.MultiIndex.from_tuples([(1,'a'), (1,'b'), (2,'a'), (2,'b')]), columns=['Var1','Var2','Var3'])
>>> df.index.names=['Number','Letter']
>>> print df
               Var1  Var2  Var3
Number Letter                  
1      a        1.0  2.00  3.00
       b        0.4  0.50  0.60
2      a        7.0  8.00  9.00
       b        0.1  0.11  0.12

我希望由字母“b”標識的兩條記錄將所有 3 個變量都乘以 10。

我正在努力解決的第一個方面是如何選擇多索引的第二個索引。 我可以通過以下草率的解決方法來做到這一點,但我想有一種更清潔的方法:

>>> df=df.reset_index().set_index(['Letter','Number'])
>>> Records=df.loc['b']
>>> print Records
        Var1  Var2  Var3
Number                  
1        0.4  0.50  0.60
2        0.1  0.11  0.12

關於在第二個索引上設置子集的更好方法有什么建議嗎?

然后我可以重新調整它們:

>>> print Records*10
        Var1  Var2  Var3
Number                  
1          4     5     6
2         10    11    12

但是,如何用這些新調整的值替換原始值?

使用 Pandas,您可以通過以下任一方式訪問 MultiIndex 中的第二級:

df.loc[df.index.isin("b", level="Letter")]
               Var1  Var2  Var3
Number Letter                  
1      b        0.4  0.50  0.60
2      b        0.1  0.11  0.12

或者

df.xs("b", level="Letter")
        Var1  Var2  Var3
Number                  
1        0.4  0.50  0.60
2        0.1  0.11  0.12

它不是完全相同的輸出,只有第一個版本允許您更改值(感謝loc以及您保留所有索引值的事實):

df.loc[df.index.isin("b", level="Letter")] = df.loc[df.index.isin("b", level="Letter")]*10

df
               Var1  Var2  Var3
Number Letter                  
1      a          1   2.0   3.0
       b          4   5.0   6.0
2      a          7   8.0   9.0
       b          1   1.1   1.2

這樣,您還可以輕松訪問您也可以修改的給定列:

df.loc[df.index.isin("b", level="Letter"), "Var3"] = "Foo"
df

               Var1  Var2 Var3
Number Letter                 
1      a          1   2.0    3
       b          4   5.0  Foo
2      a          7   8.0    9
       b          1   1.1  Foo

希望這可以幫助

如果第二個索引級別是'b' ,則按 10 倍縮放值?:

In [82]:

print pd.DataFrame(data=df.values*np.where(df.index.get_level_values(1) == 'a', 1, 10).reshape((-1,1)), 
                   index=df.index)
               0    1    2
Number Letter             
1      a       1  2.0  3.0
       b       4  5.0  6.0
2      a       7  8.0  9.0
       b       1  1.1  1.2

或者:

In [94]:

print (df.T * np.where(df.index.get_level_values(1) == 'a', 1, 10)).T
               Var1  Var2  Var3
Number Letter                  
1      a          1   2.0   3.0
       b          4   5.0   6.0
2      a          7   8.0   9.0
       b          1   1.1   1.2

我會通過 unstack 使多索引級別成為第一個,然后對其進行切片:

    In [72]: df=pd.DataFrame(data=[[1,2,3],[.4,.5,.6],[7,8,9],[.10,.11,.12]], index=pd.MultiIndex.from_tuples([(1,'a'), (1,'b'), (2,'a'), (2,'b')]),         columns=['Var1','Var2','Var3'])        

    In [73]: df
    Out[73]: 
         Var1  Var2  Var3
    1 a   1.0  2.00  3.00
      b   0.4  0.50  0.60
    2 a   7.0  8.00  9.00
      b   0.1  0.11  0.12

    In [89]: df1 = df.unstack(-2) # the same as level=0
    In [90]: df1
    Out[90]: 
       Var1       Var2        Var3      
          1    2     1     2     1     2
    a   1.0  7.0   2.0  8.00   3.0  9.00
    b   0.4  0.1   0.5  0.11   0.6  0.12

    In [91]: df1.loc['a']*=10
    In [92]: df1
    Out[92]: 
       Var1        Var2         Var3       
          1     2     1      2     1      2
    a  10.0  70.0  20.0  80.00  30.0  90.00
    b   0.4   0.1   0.5   0.11   0.6   0.12

    df = df1.stack().swaplevel(0,1) # return back to the multi-index

如果你更喜歡優雅的方式:

df.loc[(slice(None), 'b'), :]

查看更多: https : //pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM