复杂参考另一个表

时间:2016-08-28 12:05:44

标签: python pandas dataframe

我的数据框如下所示: 列名称'Types'shows每种类型都不同

我想添加另一个名为'number'的列,如下所示。

df=pd.DataFrame({'Sex':['M','F','F','M'],'Age':[30,31,33,32],'Types':['A','C','B','D']})

Out[8]: 

    Age Sex  Types
0   30   M      A
1   31   F      C
2   33   F      B
3   32   M      D

我下面还有另一张男表; 每列代表类型!

(很难为我创建表格,还有另一种简单的方法可以创建吗?)

table_M = pd.DataFrame(np.arange(20).reshape(4,5),index=[30,31,32,33],columns=["A","B","C","D","E"])
table_M.index.name="Age(male)"

         A      B      C      D      E
Age(male)                                   
30       0      1      2      3      4
31       5      6      7      8      9
32      10     11     12     13     14
33      15     16     17     18     19

我下面有女表;

table_F = pd.DataFrame(np.arange(20,40).reshape(4,5),index=[30,31,32,33],columns=["A","B","C","D","E"])
table_F.index.name="Age(female)"

        A      B      C      D      E
Age(female)                                   
30      20     21     22     23     24
31      25     26     27     28     29
32      30     31     32     33     34
33      35     36     37     38     39

所以我想添加'number'列,如下所示;

    Age Sex  Types   number
0   30   M      A      0 
1   31   F      C     27
2   33   F      B     36
3   32   M      D     13

这个数字栏是指女性和男性表。对于每个年龄,类型和性别。 这对我来说太复杂了。 我可以问一下如何添加“数字”列吗?

3 个答案:

答案 0 :(得分:5)

我建议重塑你的男女表:

males = (table_M.stack().to_frame('number').assign(Sex='M').reset_index()
                .rename(columns={'Age(male)': 'Age', 'level_1': 'Types'}))

females = (table_F.stack().to_frame('number').assign(Sex='F').reset_index()
                  .rename(columns={'Age(female)': 'Age', 'level_1': 'Types'}))

reshaped = pd.concat([males, females], ignore_index=True)

然后合并:

df.merge(reshaped)
Out: 
   Age Sex Types  number
0   30   M     A       0
1   31   F     C      27
2   33   F     B      36
3   32   M     D      13

这样做是为了堆叠男性和女性表格的列,并指定一个显示性别的指标栏(' M'和' F')。 females.head()看起来像这样:

females.head()
Out: 
   Age Types  number Sex
0   30     A      20   F
1   30     B      21   F
2   30     C      22   F
3   30     D      23   F
4   30     E      24   F

males.head()

males.head()
Out: 
   Age Types  number Sex
0   30     A       0   M
1   30     B       1   M
2   30     C       2   M
3   30     D       3   M
4   30     E       4   M

使用pd.concat,这两个组合成一个DataFrame,默认情况下合并在公共列上,因此它会在' Age',' Sex'中找到匹配项,& #39;类型'列并合并两个DataFrames。

另一种可能性是使用df.lookup:

df.loc[df['Sex']=='M', 'number'] = table_M.lookup(*df.loc[df['Sex']=='M', ['Age', 'Types']].values.T)
df.loc[df['Sex']=='F', 'number'] = table_F.lookup(*df.loc[df['Sex']=='F', ['Age', 'Types']].values.T)

df
Out: 
   Age Sex Types  number
0   30   M     A     0.0
1   31   F     C    27.0
2   33   F     B    36.0
3   32   M     D    13.0

这会查找table_M中的男性和table_F中的女性。

答案 1 :(得分:4)

如果您将两个表合并在一起,以便您可以通过'Sex'访问apply,这会更容易。

table = pd.concat([table_F, table_M], axis=1, keys=['F', 'M'])

accessor = lambda row: table.loc[row.Age, (row.Sex, row.Types)]
df['number'] = df.apply(accessor, axis=1)
df

enter image description here

答案 2 :(得分:1)

另一种方法:

In [60]: df['numbers'] = df.apply(lambda x: table_F.loc[[x.Age]][x.Types].iloc[0] if x.Sex == 'F' else table_M.loc[[x.Age]][x.Types].iloc[0], axis = 1)

In [60]: df
Out[60]: 
   Age Sex Types  numbers
0   30   M     A        0
1   31   F     C       27
2   33   F     B       36
3   32   M     D       13