我有一个基于apply
列的示例数据框,试图在其中进行dtype
:
df = pd.DataFrame(np.random.randint(0,10,size =(6,2)),columns=["A","B"])
df.loc[2,"B"]=np.NaN
df["C"]=np.NaN
df["st"]=["Mango"]*6
df["date"]=["2001-01-01","2001-01-02","2001-01-03","2001-01-04","2001-01-05","2001-01-06"]
df["date"]=pd.to_datetime(df["date"])
df
示例数据框:
A B C fruit date
0 1 1.0 NaN Mango 2001-01-01
1 4 3.0 NaN Mango 2001-01-02
2 8 NaN NaN Mango 2001-01-03
3 2 1.0 NaN Mango 2001-01-04
4 9 6.0 NaN Mango 2001-01-05
5 9 6.0 NaN Mango 2001-01-06
我正在尝试根据列DF
来转换dtypes
并生成一个row
。
伪代码:
if data_type(column) == String:
#first value in the column
return column_value[0]
if data_type(column) == datetime:
#last value in the column
return column_value[-1]
if data_type(column) == int or data_type(column) == float:
if all_values_in_column==np.NaN:
return np.NaN
else:
#mean of the column
return mean(column)
代码:
from pandas.api.types import is_datetime64_any_dtype as is_datetime
from pandas.api.types import is_float,is_float_dtype,is_integer,is_integer_dtype
def check(series):
if is_string_dtype(series)==True:
return series[0]
elif is_datetime(series) == True:
return series[len(series)-1]
elif is_integer_dtype(series) ==True or is_float_dtype(series):
if series.isnull().all()==True:
return np.NaN
else:
return series.fillna(0).mean()
op = pd.DataFrame(df.apply(check)).transpose()
当前输出:
A B C st date
0 1 1 NaN Mango 2001-01-01 00:00:00
除了C
和st
列以外,我得到的输出是错误的。
预期输出:
A B C st date
0 5.5 2.833 NaN Mango 2001-01-06 00:00:00
关于错误的任何建议可能会有所帮助?
答案 0 :(得分:3)
根据此Why does apply change dtype in pandas dataframe columns
您需要在申请中使用result_type='expand'
def check(series):
if is_string_dtype(series)==True:
return series[0]
elif is_datetime(series) == True:
return series[len(series)-1]
elif is_integer_dtype(series) ==True or is_float_dtype(series):
if series.isnull().all()==True:
return np.NaN
else:
return series.fillna(0).mean()
op = pd.DataFrame(df.apply(check, result_type='expand')).transpose()
op
答案 1 :(得分:1)
一个简单的解决方案是遍历所有列并将结果保存在字典中,然后创建一个新的数据框。可以完成以下操作:
from pandas.api.types import is_datetime64_any_dtype as is_datetime
from pandas.api.types import is_float_dtype, is_integer_dtype
res = dict()
for col, dtype in df.dtypes.items():
print(col, dtype)
if is_float_dtype(dtype) or is_integer_dtype(dtype):
if df[col].isnull().all():
res[col] = np.nan
else:
res[col] = df[col].fillna(0).mean()
elif dtype == object:
res[col] = df[col].iloc[0]
elif is_datetime(dtype):
res[col] = df[col].iloc[-1]
op = pd.DataFrame(res, index=[0])
结果:
A B C fruit date
0 5.5 2.833333 NaN Mango 2001-01-06
答案 2 :(得分:1)
引用df.apply
documentation
由于df.apply,您遇到了这个问题,它返回了一系列dtype对象的熊猫。
尝试一下:
def check(series):
print(series.dtype)
return 0
您将获得:
>>object
>>object
>>object
>>object
>>object
因此,不要使用
op = pd.DataFrame(df.apply(check)).transpose()
使用
op = pd.DataFrame(df.apply(check), result_type = 'expand').transpose()