根据模板在PYTHON中使用匹配的列名称更改熊猫数据框列的数据类型

时间:2018-10-08 00:29:50

标签: python python-3.x pandas dataframe pandas-groupby

我有2个数据框。

  • 模板-我将使用此数据框中的数据类型。
  • df-我想基于模板更改此数据框的数据类型。

我想基于第一个更改第二个数据帧的数据类型。假设我有下面的数据框用作模板。

.ad-indicator {
    display: none ;
}

我正在寻找下面的东西。

  • 要在df中将模板的数据类型强制转换为完全相同。
  • 它应该与模板框架中的列相同。

**注意-如果df中不可用,则应添加带有所有NA的其他列。

> template
id <- c(1,2,3,4)
a <- c(1,4,5,6)
b <- as.character(c(0,1,1,4))
c <- as.character(c(0,1,1,0))
d <- c(0,1,1,0)
template <- data.frame(id,a,b,c,d, stringsAsFactors = FALSE)

> str(template)
'data.frame':   4 obs. of  5 variables:
 $ id: num  1 2 3 4
 $ a : num  1 4 5 6
 $ b : chr  "0" "1" "1" "4"
 $ c : chr  "0" "1" "1" "0"
 $ d : num  0 1 1 0

所需的输出-

> df
id <- c(6,7,12,14,1,3,4,4)
a <- c(0,1,13,1,3,4,5,6)
b <- c(1,4,12,3,4,5,6,7)
c <- c(0,0,13,3,4,45,6,7)
e <- c(0,0,13,3,4,45,6,7)
df <- data.frame(id,a,b,c,e)

> str(df)
'data.frame':   8 obs. of  5 variables:
 $ id: num  6 7 12 14 1 3 4 4
 $ a : num  0 1 13 1 3 4 5 6
 $ b : num  1 4 12 3 4 5 6 7
 $ c : num  0 0 13 3 4 45 6 7
 $ e : num  0 0 13 3 4 45 6 7

通过@Frank的解决方案。

> output
    id  a  b  c  d
    1  6  0  1  0 NA
    2  7  1  4  0 NA
    3 12 13 12 13 NA
    4 14  1  3  3 NA
    5  1  3  4  4 NA
    6  3  4  5 45 NA
    7  4  5  6  6 NA
    8  4  6  7  7 NA

> str(output)

'data.frame':   8 obs. of  5 variables:
 $ id: num  6 7 12 14 1 3 4 4
 $ a : num  0 1 13 1 3 4 5 6
 $ b : chr  "1" "4" "12" "3" ...
 $ c : chr  "0" "0" "13" "3" ...
 $ d : logi  NA NA NA NA NA NA ...

注意-我正在尝试在Python中做同样的事情。我是python新手,不知道如何使用。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

您的问题通常无法解决,因为熊猫(numpy)中没有integer NaN也没有booleane NaN。要存储NaN,应提升数据类型https://pandas.pydata.org/pandas-docs/stable/gotchas.html#support-for-integer-na。您可以这样做:

import numpy as np
import pandas as pd

TEMPLATE = pd.DataFrame(
    {'id': pd.Series(dtype=int),
     'a': pd.Series(dtype=int),
     'b': pd.Series(dtype=str),
     'c': pd.Series(dtype=str),
     'd': pd.Series(dtype=bool)})


def modify_with_template(df, template):

    # type promotion
    df_dtypes = df.dtypes.to_dict()
    t_dtypes = template.dtypes.to_dict()

    to_promote_int = {
        col: np.float_
        for col in set(t_dtypes.keys()).difference(df_dtypes.keys())
        if issubclass(t_dtypes[col].type, np.integer)}
    to_promote_bool = {
        col: np.object_
        for col in set(t_dtypes.keys()).difference(df_dtypes.keys())
        if t_dtypes[col].type is np.bool_}

    t_dtypes.update(to_promote_int)
    t_dtypes.update(to_promote_bool)

    # actual modifying
    return df.reindex(template.columns, axis=1).astype(t_dtypes)


df = pd.DataFrame({'id': ['1', '0', '1']})
print(df)
df = modify_with_template(df, TEMPLATE)
print(df)

输出:

  id
0  1
1  0
2  1
    a    b    c    d  id
0 NaN  NaN  NaN  NaN   1
1 NaN  NaN  NaN  NaN   0
2 NaN  NaN  NaN  NaN   1