将两列的非空值合并为一列
Combing non-null values from two columns into one column
我正在关注:https://medium.com/@anateresa.mdneto/starbucks-capstone-project-79f84b2a1558
数据来自文章中的链接。
最初使用此代码加载数据:
file1 = "e:\python\pandas\datasets\Starbucks\portfolio.json"
portfolio = pd.read_json(file1, orient='records', lines=True)
file2 = "e:\python\pandas\datasets\Starbucks\profile.json"
profile = pd.read_json(file2, orient='records', lines=True)
file3 = "e:\python\pandas\datasets\Starbucks\transcript.json"
transcript = pd.read_json(file3, orient='records', lines=True)
我有一个 df(成绩单),其中一列值是字典。大多数字典是一对 key:value,但有些字典有两个 key:value 对。
我从 extracting\exploding 字典列开始,以便为每个键获得一个新列。
有四个唯一键,我得到四个新列。
我还打印了 head() 并检查了 notnull() 计数:
transcript_cp = transcript.copy(deep=True)
transcript_cp = transcript_cp.join(pd.DataFrame(transcript_cp.pop('value').values.tolist()))
print(transcript_cp.head(), '\n')
print(transcript_cp['offer id'].notnull().sum())
print(transcript_cp['amount'].notnull().sum())
print(transcript_cp['offer_id'].notnull().sum())
print(transcript_cp['reward'].notnull().sum(), '\n')
输出:
person event time offer id amount offer_id reward
0 78afa995795e4d85b5d9ceeca43f5fef offer received 0 9b98b8c7a33c4b65b9aebfe6a799e6d9 NaN NaN NaN
1 a03223e636434f42ac4c3df47e8bac43 offer received 0 0b1e1539f2cc45b7b9fa7c272da2e1d7 NaN NaN NaN
2 e2127556f4f64592b11af22de27a7932 offer received 0 2906b810c7d4411798c6938adc9daaa5 NaN NaN NaN
3 8ec6ce2a7e7949b1bf142def7d0e0586 offer received 0 fafdcd668e3743c1bb461111dcafc2a4 NaN NaN NaN
4 68617ca6246f4fbc85e91a2a49552598 offer received 0 4d5c57ea9a6940dd891ad53e9dbe8da0 NaN NaN NaN
134002
138953
33579
33579
'offer id'和'offer_id'其实是一回事。名称中有错别字,所以我 want\need 将这两列合并为一个列。
为了使其正常工作,必须满足以下假设:
- 我不能在同一行的每一列中包含非空值,否则我将直接覆盖这些值。
- 我可以在两列中使用空值。
- 我在一列中有一个非空值而在另一列中有一个空值,我想要一个只有非空值的新列。
以下是我如何证明我的假设是正确的:
df1 = transcript_cp.isna()
df2 = pd.crosstab(df1['offer id'], df1['offer_id'])
print(df2)
offer_id False True
offer id
False 0 134002
True 33579 138953
False\False == not null\not null There are zero instances of both columns being non null for any given single row.
False\True == not null\null There are 134002 instances where 'offer id' is not null but 'offer_id' is.
True\False == null\not null There are 33579 instances where 'offer id' is null but 'offer_id' is not.
True\True == null\null There are 138953 instances where both are null.
要创建一个包含 'offer id' 和 'offer_id' 值的新行,我正在使用 np.where.
transcript_cp['TEMP'] = np.where(transcript_cp['offer_id'] != np.nan, transcript_cp['offer_id'], transcript_cp['offer id'])
但是,我的非 null 值总和永远不会达到 134002 + 33579 = 167581。
使用上面的 np.where 代码我得到 33579。
如果我翻转 'offer id' 和 'offer_id'(见下文),这对我来说应该没有任何区别,我得到 134002。
transcript_cp['TEMP'] = np.where(transcript_cp['offer id'] != np.nan, transcript_cp['offer id'], transcript_cp['offer_id'])
我没有正确使用 np.where 吗?我以为它是这样写的:if condtion True, result1 else result2.
所以我是说如果选中的列不为空,return 那个值,否则 return 另一列中的值。
根据我的交叉表结果,我相信我应该得到 167581 个非空值,并且我执行 np.where.
的顺序应该没有任何区别
np.nan != np.nan
计算为 True
。所以这两个命令之间存在差异(当offer id
是nan
时会发生什么?)。
你为什么不直接使用 fillna
:
transcript_cp['offer id'].fillna(transcript_cp['offer_id'])
我正在关注:https://medium.com/@anateresa.mdneto/starbucks-capstone-project-79f84b2a1558 数据来自文章中的链接。
最初使用此代码加载数据:
file1 = "e:\python\pandas\datasets\Starbucks\portfolio.json"
portfolio = pd.read_json(file1, orient='records', lines=True)
file2 = "e:\python\pandas\datasets\Starbucks\profile.json"
profile = pd.read_json(file2, orient='records', lines=True)
file3 = "e:\python\pandas\datasets\Starbucks\transcript.json"
transcript = pd.read_json(file3, orient='records', lines=True)
我有一个 df(成绩单),其中一列值是字典。大多数字典是一对 key:value,但有些字典有两个 key:value 对。
我从 extracting\exploding 字典列开始,以便为每个键获得一个新列。
有四个唯一键,我得到四个新列。
我还打印了 head() 并检查了 notnull() 计数:
transcript_cp = transcript.copy(deep=True)
transcript_cp = transcript_cp.join(pd.DataFrame(transcript_cp.pop('value').values.tolist()))
print(transcript_cp.head(), '\n')
print(transcript_cp['offer id'].notnull().sum())
print(transcript_cp['amount'].notnull().sum())
print(transcript_cp['offer_id'].notnull().sum())
print(transcript_cp['reward'].notnull().sum(), '\n')
输出:
person event time offer id amount offer_id reward
0 78afa995795e4d85b5d9ceeca43f5fef offer received 0 9b98b8c7a33c4b65b9aebfe6a799e6d9 NaN NaN NaN
1 a03223e636434f42ac4c3df47e8bac43 offer received 0 0b1e1539f2cc45b7b9fa7c272da2e1d7 NaN NaN NaN
2 e2127556f4f64592b11af22de27a7932 offer received 0 2906b810c7d4411798c6938adc9daaa5 NaN NaN NaN
3 8ec6ce2a7e7949b1bf142def7d0e0586 offer received 0 fafdcd668e3743c1bb461111dcafc2a4 NaN NaN NaN
4 68617ca6246f4fbc85e91a2a49552598 offer received 0 4d5c57ea9a6940dd891ad53e9dbe8da0 NaN NaN NaN
134002
138953
33579
33579
'offer id'和'offer_id'其实是一回事。名称中有错别字,所以我 want\need 将这两列合并为一个列。
为了使其正常工作,必须满足以下假设:
- 我不能在同一行的每一列中包含非空值,否则我将直接覆盖这些值。
- 我可以在两列中使用空值。
- 我在一列中有一个非空值而在另一列中有一个空值,我想要一个只有非空值的新列。
以下是我如何证明我的假设是正确的:
df1 = transcript_cp.isna()
df2 = pd.crosstab(df1['offer id'], df1['offer_id'])
print(df2)
offer_id False True
offer id
False 0 134002
True 33579 138953
False\False == not null\not null There are zero instances of both columns being non null for any given single row.
False\True == not null\null There are 134002 instances where 'offer id' is not null but 'offer_id' is.
True\False == null\not null There are 33579 instances where 'offer id' is null but 'offer_id' is not.
True\True == null\null There are 138953 instances where both are null.
要创建一个包含 'offer id' 和 'offer_id' 值的新行,我正在使用 np.where.
transcript_cp['TEMP'] = np.where(transcript_cp['offer_id'] != np.nan, transcript_cp['offer_id'], transcript_cp['offer id'])
但是,我的非 null 值总和永远不会达到 134002 + 33579 = 167581。
使用上面的 np.where 代码我得到 33579。
如果我翻转 'offer id' 和 'offer_id'(见下文),这对我来说应该没有任何区别,我得到 134002。
transcript_cp['TEMP'] = np.where(transcript_cp['offer id'] != np.nan, transcript_cp['offer id'], transcript_cp['offer_id'])
我没有正确使用 np.where 吗?我以为它是这样写的:if condtion True, result1 else result2.
所以我是说如果选中的列不为空,return 那个值,否则 return 另一列中的值。
根据我的交叉表结果,我相信我应该得到 167581 个非空值,并且我执行 np.where.
的顺序应该没有任何区别np.nan != np.nan
计算为 True
。所以这两个命令之间存在差异(当offer id
是nan
时会发生什么?)。
你为什么不直接使用 fillna
:
transcript_cp['offer id'].fillna(transcript_cp['offer_id'])