python - 使用过滤视图插入原始数据框
问题描述
我使用如下稀疏数据框:
df = pd.DataFrame.from_dict({'type': {581: 'A', 1638: 'B', 706: 'C', 422: 'B', 487: 'A', 1503: 'D', 1948: 'B', 700: 'E', 2040: 'D', 1664: 'C'}, 'set1_a': {581: 27.08, 1638: np.nan, 706: 92.37, 422: np.nan, 487: np.nan, 1503: np.nan, 1948: np.nan, 700: np.nan, 2040: np.nan, 1664: np.nan}, 'set1_b': {581: 68.0, 1638: np.nan, 706: 0.0, 422: np.nan, 487: np.nan, 1503: np.nan, 1948: np.nan, 700: np.nan, 2040: np.nan, 1664: np.nan}, 'set2_a': {581: np.nan, 1638: np.nan, 706: np.nan, 422: np.nan, 487: np.nan, 1503: np.nan, 1948: np.nan, 700: 21.99, 2040: np.nan, 1664: np.nan}, 'set2_b': {581: np.nan, 1638: np.nan, 706: np.nan, 422: np.nan, 487: np.nan, 1503: np.nan, 1948: np.nan, 700: 92.91, 2040: np.nan, 1664: np.nan}, 'set3_a': {581: 28.56, 1638: 21.79, 706: 95.15, 422: 45.1, 487: 65.33, 1503: 85.6, 1948: 51.5, 700: 98.14, 2040: 40.37, 1664: 66.18}, 'set3_b': {581: 68.0, 1638: 59.3, 706: 0.0, 422: 51.42, 487: 59.07, 1503: 57.1, 1948: 34.6, 700: 6.02, 2040: 8.25, 1664: 58.47}})
type set1_a set1_b set2_a set2_b set3_a set3_b
581 A 27.08 68.0 NaN NaN 28.56 68.00
1638 B NaN NaN NaN NaN 21.79 59.30
706 C 92.37 0.0 NaN NaN 95.15 0.00
422 B NaN NaN NaN NaN 45.10 51.42
487 A NaN NaN NaN NaN 65.33 59.07
1503 D NaN NaN NaN NaN 85.60 57.10
1948 B NaN NaN NaN NaN 51.50 34.60
700 E NaN NaN 21.99 92.91 98.14 6.02
2040 D NaN NaN NaN NaN 40.37 8.25
1664 C NaN NaN NaN NaN 66.18 58.47
set1_a
我的目标是set1_b
根据应用于type
. 每种类型都可以分配给某个组,如下所示:
type_group1 = ['A', 'C', 'B', 'D']
type_group2 = ['E', 'F', 'G']
规则如下:
- If
type
is intype_group1
then ifset1_a
and already have values then leave them as is ,set1_b
否则分配给他们。set3_a
set3_b
- If
type
is intype_group2
then 分别赋值set2_a
和set2_b
到set1_a
和set2_b
。
真正的类型和类型组要复杂得多,所以为了代码简洁,我想创建 Pandas 视图并使用它们进行分配,如下所示:
type_group1_df = df[df['type'].isin(type_group1)]
type_group1_df.loc[type_group1_df['set1_a'].isnull(), 'set1_a'] = type_group1_df['set3_a']
type_group1_df.loc[type_group1_df['set1_b'].isnull(), 'set1_b'] = type_group1_df['set3_b']
type_group2_df = df[df['type'].isin(type_group2)]
type_group2_df[['set1_a', 'set1_b']] = type_group2_df[['set2_a', 'set2_b']]
但是,两者都返回一个新的数据框,而不是插入到原始的df
. 因此,我相信他们正在创建内部 df 的副本,而不是视图。如何创建 Pandas 视图以插入原始视图df
?
预期的输出将是:
type set1_a set1_b set2_a set2_b set3_a set3_b
581 A 27.08 68.00 NaN NaN 28.56 68.00
1638 B 21.79 59.30 NaN NaN 21.79 59.30
706 C 92.37 0.00 NaN NaN 95.15 0.00
422 B 45.10 51.42 NaN NaN 45.10 51.42
487 A 65.33 59.07 NaN NaN 65.33 59.07
1503 D 85.60 57.10 NaN NaN 85.60 57.10
1948 B 51.50 34.60 NaN NaN 51.50 34.60
700 E 21.99 92.91 21.99 92.91 98.14 6.02
2040 D 40.37 8.25 NaN NaN 40.37 8.25
1664 C 66.18 58.47 NaN NaN 66.18 58.47
解决方案
您可以使用具有相关条件的numpy.where来获取所需的数据框:
cond_set1a = (df.type.isin(type_group1)) & df.set1_a.isna()
cond_set1b = (df.type.isin(type_group1)) & df.set1_b.isna()
cond_set2 = df.type.isin(type_group2)
df['set1_a'] = np.where(cond_set1a, df.set3_a,df.set1_a)
df['set1_b'] = np.where(cond_set1b, df.set3_b,df.set1_b)
df['set1_a'] = np.where(cond_set2, df.set2_a, df.set1_a)
df['set1_b'] = np.where(cond_set2, df.set2_b, df.set1_b)
df
type set1_a set1_b set2_a set2_b set3_a set3_b
581 A 27.08 27.08 NaN NaN 28.56 68.00
1638 B 21.79 21.79 NaN NaN 21.79 59.30
706 C 92.37 92.37 NaN NaN 95.15 0.00
422 B 45.10 45.10 NaN NaN 45.10 51.42
487 A 65.33 65.33 NaN NaN 65.33 59.07
1503 D 85.60 85.60 NaN NaN 85.60 57.10
1948 B 51.50 51.50 NaN NaN 51.50 34.60
700 E 21.99 92.91 21.99 92.91 98.14 6.02
2040 D 40.37 40.37 NaN NaN 40.37 8.25
1664 C 66.18 66.18 NaN NaN 66.18 58.47
根据您的用例,@Henry 的 numpy select 将提供更简洁的方法。
推荐阅读
- python - 分块列表打印“0x05DAF8D0 处的生成器对象块”而不是列表
- wordpress - WordPress更新后修改的CSS
- c++ - 具有类型特征的通用 lambda
- javascript - 我可以在一页中的多个表单上使用多个 onsubmit 事件吗
- sql - SQL 转换数据
- html - HTML/CSS - 如何将三个中间的 div 居中,独立于周围的 div
- python - 来自 Ordered Dict 的 Python Json
- javascript - 递归 JQuery 以在文本中格式化 HTML 节点值
- android - 如何为两个视图设置约束?
- java - 如何使用 Java 反射从文件中读取类和对象名称?