pandas dataframe

时间:2017-05-11 19:06:38

标签: python pandas

我有一个具有以下结构的数据框:

    date    kind    sector
0   2017-02-01  P   A
1   2017-02-01  P   A
2   2017-02-01  L   A
3   2017-02-01  G   A
4   2017-02-01  P   B
5   2017-02-01  P   B
6   2017-02-01  L   B
7   2017-02-01  T   B
8   2017-02-02  P   A
9   2017-02-02  P   A
10  2017-02-02  L   A
11  2017-02-02  T   A
12  2017-02-02  A   B
13  2017-02-02  P   B
14  2017-02-02  L   B
15  2017-02-02  L   B

我想创建一个格式为

的聚合
    date      sector free occupied total
   2017-02-01  A      2    2         4
   2017-02-01  B      2    2         4
   2017-02-02  A      2    2         4
   2017-02-02  A      3    1         4

其中规则是如果kind == P被占用,则else是空闲的,而total是所有条目的总和。我尝试在一个组中使用apply,但它不起作用:

df.groupby(['date', 'kind']).apply(lambda x: 1 if x == 'P' else 0)

拆分数据框并进行组合也无法正常工作:

df_p = df[df.kind == 'P']
df_np = df[df.kind != 'P']
df_t = df_p.groupby(['date', 'sector'], as_index=False).count()
df_nt = df_np.groupby(['date', 'sector'], as_index=False).count()
df_nt.rename(columns={'kind':'free'}, inplace=True)
df_t = pd.concat([df_t, df_nt])

有没有办法做到这一点?

3 个答案:

答案 0 :(得分:2)

为“已占用”和“免费”创建两个新变量:

df['occupied'] = (df.kind == "P").astype(int)
df['free'] = (df.kind != "P").astype(int)

然后聚合(使用OrderedDict此处而不是dict来实现所需的输出列排序):

df_2 = (
    df.groupby(["date","sector"])
    .agg(OrderedDict((("free" , np.sum) , ("occupied" , np.sum))))
)

创建总栏目:

df_2["total"] = df_2["free"] + df_2["occupied"]

输出:

enter image description here

答案 1 :(得分:0)

尝试:

df['kind'] = df.kind.apply(lambda x: 'occupied' if x == 'P' else 'free')
df1 = pd.get_dummies(df.kind).join(df).groupby(['date','sector']).sum().reset_index()
df1['total'] = df1['occupied']+df1['free']    
df1

    #          date sector  free  occupied  total
    # 0  2017-02-01      A     2         2      4
    # 1  2017-02-01      B     2         2      4
    # 2  2017-02-02      A     2         2      4
    # 3  2017-02-02      B     3         1      4

您基本上在这里做的是:您首先用kind列中的被占用和其他所有内容免费替换P.然后,您将新格式化的kind中的值与pd.get_dummies分类。然后将该输出连接回主数据帧。此时,您可以按datesector分组,并获取每个sum。最终,您可以reset_index并计算total列。

我希望这会有所帮助。

答案 2 :(得分:0)

这是一个单行代码:

`function get_pwd() { 
    echo "${PWD/$HOME/~}"
}
local ret_status="%(?:%{$fg_bold[green]%}➜ :%{$fg_bold[red]%}➜ %s)
"PROMPT='%{$fg[white]%}$USER%{$fg[cyan]%}%M ${ret_status}%{$fg_bold[green]%}%p %{$fg[yellow]%}$(get_pwd)%{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%} % %{$reset_color%}'
ZSH_THEME_GIT_PROMPT_PREFIX="❮ %{$fg[red]%}"
ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}❯ %{$fg[yellow]%}%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%}❯"

更详细的方法:

#group by date and sector, apply 3 functions to kind to get the sum for free, occupied and total in one go.
df.groupby(['date','sector'])['kind'].agg({'free':lambda x: sum(x!='P'),'occupied':lambda x: sum(x=='P'), 'total':len})
Out[339]: 
                   free  occupied  total
date       sector                       
2017-02-01 A          2         2      4
           B          2         2      4
2017-02-02 A          2         2      4
           B          3         1      4