Python将qcut应用于多索引数据帧中多索引的0级分组
我在pandas(日期和实体id)中有一个多索引数据框,对于每个日期/实体,我有许多变量(a、B…)的观测值。我的目标是创建一个具有相同形状的数据框,但其中的值被其十分位数替换 我的测试数据如下所示: 我想将qcut应用于按多索引的级别0分组的每个列——我遇到的问题是创建一个结果数据框 此代码Python将qcut应用于多索引数据帧中多索引的0级分组,python,pandas,apply,multi-index,Python,Pandas,Apply,Multi Index,我在pandas(日期和实体id)中有一个多索引数据框,对于每个日期/实体,我有许多变量(a、B…)的观测值。我的目标是创建一个具有相同形状的数据框,但其中的值被其十分位数替换 我的测试数据如下所示: 我想将qcut应用于按多索引的级别0分组的每个列——我遇到的问题是创建一个结果数据框 此代码 def qcut_sub_index(df_with_sub_index): # create empty return value same shape as passed dataframe
def qcut_sub_index(df_with_sub_index):
# create empty return value same shape as passed dataframe
df_return=pd.DataFrame()
for date, sub_df in df_with_sub_index.groupby(level=0):
df_return=df_return.append(pd.DataFrame(pd.qcut(sub_df, 10, labels=False, duplicates='drop')))
print(df_return)
return df_return
print(df_values.apply(lambda x: qcut_sub_index(x), axis=0))
返回
A
as_at_date entity_id
2008-01-27 2928 0
2932 3
3083 6
3333 9
2008-02-27 2928 3
2935 9
3333 0
3874 6
2008-03-27 2928 1
2932 2
2934 0
2936 9
2937 4
2939 9
2940 7
2943 3
2944 0
2945 8
2946 6
2947 5
2949 4
B
as_at_date entity_id
2008-01-27 2928 9
2932 6
3083 0
3333 3
2008-02-27 2928 6
2935 0
3333 3
3874 9
2008-03-27 2928 0
2932 9
2934 2
2936 8
2937 7
2939 6
2940 3
2943 1
2944 4
2945 9
2946 5
2947 4
2949 0
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-104-72ff0e6da288> in <module>
11
12
---> 13 print(df_values.apply(lambda x: qcut_sub_index(x), axis=0))
~\Anaconda3\lib\site-packages\pandas\core\frame.py in apply(self, func, axis, raw, result_type, args, **kwds)
7546 kwds=kwds,
7547 )
-> 7548 return op.get_result()
7549
7550 def applymap(self, func) -> "DataFrame":
~\Anaconda3\lib\site-packages\pandas\core\apply.py in get_result(self)
178 return self.apply_raw()
179
--> 180 return self.apply_standard()
181
182 def apply_empty_result(self):
~\Anaconda3\lib\site-packages\pandas\core\apply.py in apply_standard(self)
272
273 # wrap results
--> 274 return self.wrap_results(results, res_index)
275
276 def apply_series_generator(self) -> Tuple[ResType, "Index"]:
~\Anaconda3\lib\site-packages\pandas\core\apply.py in wrap_results(self, results, res_index)
313 # see if we can infer the results
314 if len(results) > 0 and 0 in results and is_sequence(results[0]):
--> 315 return self.wrap_results_for_axis(results, res_index)
316
317 # dict of scalars
~\Anaconda3\lib\site-packages\pandas\core\apply.py in wrap_results_for_axis(self, results, res_index)
369
370 try:
--> 371 result = self.obj._constructor(data=results)
372 except ValueError as err:
373 if "arrays must all be same length" in str(err):
~\Anaconda3\lib\site-packages\pandas\core\frame.py in __init__(self, data, index, columns, dtype, copy)
466
467 elif isinstance(data, dict):
--> 468 mgr = init_dict(data, index, columns, dtype=dtype)
469 elif isinstance(data, ma.MaskedArray):
470 import numpy.ma.mrecords as mrecords
~\Anaconda3\lib\site-packages\pandas\core\internals\construction.py in init_dict(data, index, columns, dtype)
281 arr if not is_datetime64tz_dtype(arr) else arr.copy() for arr in arrays
282 ]
--> 283 return arrays_to_mgr(arrays, data_names, index, columns, dtype=dtype)
284
285
~\Anaconda3\lib\site-packages\pandas\core\internals\construction.py in arrays_to_mgr(arrays, arr_names, index, columns, dtype, verify_integrity)
76 # figure out the index, if necessary
77 if index is None:
---> 78 index = extract_index(arrays)
79 else:
80 index = ensure_index(index)
~\Anaconda3\lib\site-packages\pandas\core\internals\construction.py in extract_index(data)
385
386 if not indexes and not raw_lengths:
--> 387 raise ValueError("If using all scalar values, you must pass an index")
388
389 if have_series:
ValueError: If using all scalar values, you must pass an index
A
截至日期实体id
2008-01-27 2928 0
2932 3
3083 6
3333 9
2008-02-27 2928 3
2935 9
3333 0
3874 6
2008-03-27 2928 1
2932 2
2934 0
2936 9
2937 4
2939 9
2940 7
2943 3
2944 0
2945 8
2946 6
2947 5
2949 4
B
截至日期实体id
2008-01-27 2928 9
2932 6
3083 0
3333 3
2008-02-27 2928 6
2935 0
3333 3
3874 9
2008-03-27 2928 0
2932 9
2934 2
2936 8
2937 7
2939 6
2940 3
2943 1
2944 4
2945 9
2946 5
2947 4
2949 0
---------------------------------------------------------------------------
ValueError回溯(最近一次调用上次)
在里面
11
12
--->13打印(df_值。应用(λx:qcut_子索引(x),轴=0))
应用中的~\Anaconda3\lib\site packages\pandas\core\frame.py(self、func、axis、raw、result\u type、args、**kwds)
7546科威特第纳尔=科威特第纳尔,
7547 )
->7548返回操作获取结果()
7549
7550 def applymap(self,func)->“数据帧”:
获取结果(self)中的~\Anaconda3\lib\site packages\pandas\core\apply.py
178返回自我。应用_原始()
179
-->180返回自我应用标准()
181
182 def应用\空\结果(自身):
应用标准中的~\Anaconda3\lib\site packages\pandas\core\apply.py(self)
272
273#总结结果
-->274返回self.wrap\u结果(结果、res\u索引)
275
276 def apply_series_生成器(self)->元组[ResType,“Index”]:
包装结果中的~\Anaconda3\lib\site packages\pandas\core\apply.py(self、results、res\u索引)
看看我们能否推断出结果
314如果len(results)>0且结果中为0且为_序列(results[0]):
-->315返回自身。为_轴(结果、分辨率索引)换行_结果
316
317标量表
~\Anaconda3\lib\site packages\pandas\core\apply.py in wrap\u results\u for\u axis(self、results、res\u index)
369
370尝试:
-->371结果=self.obj.\u构造函数(数据=结果)
372除ValueError作为错误外:
373如果str中的“数组长度必须相同”(err):
~\Anaconda3\lib\site packages\pandas\core\frame.py in\uuuuuu init\uuuuuuu(self、data、index、columns、dtype、copy)
466
467 elif isinstance(数据、指令):
-->468 mgr=init_dict(数据、索引、列、数据类型=dtype)
469 elif isinstance(数据,ma.MaskedArray):
470导入numpy.ma.mrecords作为mrecords
init_dict中的~\Anaconda3\lib\site packages\pandas\core\internals\construction.py(数据、索引、列、数据类型)
281 arr如果不是,则为数组中的arr的\u datetime64tz\u数据类型(arr)else arr.copy()
282 ]
-->283将数组\u返回给\u mgr(数组、数据\u名称、索引、列,dtype=dtype)
284
285
~\Anaconda3\lib\site packages\pandas\core\internals\construction.py in arrays\u to\u mgr(数组、arr\u名称、索引、列、数据类型、验证\u完整性)
76#如有必要,找出索引
77如果索引为无:
--->78索引=提取索引(数组)
79.其他:
80指数=确保指数(指数)
提取索引(数据)中的~\Anaconda3\lib\site packages\pandas\core\internals\construction.py
385
386如果不是索引和非原始长度:
-->387 raise VALUERROR(“如果使用所有标量值,则必须传递索引”)
388
389如果有_系列:
ValueError:如果使用所有标量值,则必须传递索引
所以有什么东西阻止了lambda函数的第二次应用
谢谢你的帮助,谢谢你看一看
p、 如果这可以在不使用apply的情况下简单地实现,我很乐意听到。谢谢在原始数据帧上的迭代中使用
concat
可以实现这一点,但是有更聪明的方法吗
谢谢
def qcut_sub_index(df_with_sub_index):
# create empty return value same shape as passed dataframe
df_return=pd.DataFrame()
for date, sub_df in df_with_sub_index.groupby(level=0):
df_return=df_return.append(pd.DataFrame(pd.qcut(sub_df, 10, labels=False,
duplicates='drop')))
return df_return
df_x=pd.DataFrame()
for (columnName, columnData) in df_values.iteritems():
df_x=pd.concat([df_x, qcut_sub_index(columnData)], axis=1, join="outer")
df_x
在原始数据帧上的迭代中使用
concat
可以达到这个目的,但是有没有更聪明的方法呢
谢谢
def qcut_sub_index(df_with_sub_index):
# create empty return value same shape as passed dataframe
df_return=pd.DataFrame()
for date, sub_df in df_with_sub_index.groupby(level=0):
df_return=df_return.append(pd.DataFrame(pd.qcut(sub_df, 10, labels=False,
duplicates='drop')))
return df_return
df_x=pd.DataFrame()
for (columnName, columnData) in df_values.iteritems():
df_x=pd.concat([df_x, qcut_sub_index(columnData)], axis=1, join="outer")
df_x
您的解决方案似乎过于复杂。您的术语不标准,多索引有级别。由多索引的级别0表示为
qcut()
(不讨论不属于概念的子帧)
把一切都恢复到一起
- 对于数据框中的所有列,使用
方法将参数传递给**kwargs
assign()
与日期一致groupby(level=0)
为索引中的每个条目返回一行transform()
你的解决方案似乎过于复杂。您的术语不标准,多索引有级别。由多索引的级别0表示为
qcut()
(不讨论不属于概念的子帧)
带来
A B
as_at_date entity_id
2020-01-31 2926 0.770121 2.883519e+07
2943 0.187747 1.167975e+08
2973 0.371721 3.133071e+07
3104 0.243347 4.497294e+08
3253 0.591022 7.796131e+08
3362 0.810001 6.438441e+08
2020-02-29 3185 0.690875 4.513044e+08
3304 0.311436 4.561929e+07
2020-03-31 2953 0.325846 7.770111e+08
2981 0.918461 7.594753e+08
3034 0.133053 6.767501e+08
3355 0.624519 6.318104e+07
A B
as_at_date entity_id
2020-01-31 2926 7 0
2943 0 3
2973 3 1
3104 1 5
3253 5 9
3362 9 7
2020-02-29 3185 9 9
3304 0 0
2020-03-31 2953 3 9
2981 9 6
3034 0 3
3355 6 0