如何做比 pandas DataFrame 合并更好的 than/less?
How to do greater than/less than binning with pandas DataFrame?
我有一个 pandas DataFrame 如下:
import pandas as pd
import numpy as np
data = {"first_column": ["item1", "item2", "item3", "item4", "item5", "item6", "item7"],
"second_column": ["cat1", "cat1", "cat1", "cat2", "cat2", "cat2", "cat2"],
"third_column": [5, 1, 8, 3, 731, 189, 9]}
df = pd.DataFrame(data)
df
first_column second_column third_column
0 item1 cat1 5
1 item2 cat1 1
2 item3 cat1 8
3 item4 cat2 3
4 item5 cat2 731
5 item6 cat2 189
6 item7 cat2 9
现在,假设我想使用 pandas.cut()
创建第四列来显示第三列的分类。这里,我在每一行标注third_column
中的元素是否小于等于十,<=10
。
df["less_than_ten"]= pd.cut(df.third_column, [-np.inf, 10, np.inf], labels=(1,0))
现在生成的数据框是:
first_column second_column third_column less_than_ten
0 item1 cat1 5 1
1 item2 cat1 1 1
2 item3 cat1 8 1
3 item4 cat2 3 1
4 item5 cat2 731 0
5 item6 cat2 189 0
6 item7 cat2 9 1
问题:请注意第二列 second_column
,类别为 cat1
和 cat2
。我将如何使用 pandas.cut()
根据 second_column
中的 "class" 对这些值进行重新分类?
更重要的是,假设我想要更复杂的间隔,例如小于或等于 500 le(500) 且大于或等于 20 ge(20)?这将如何完成?在这种情况下,应该有一个 1 标记为分组:
first_column second_column third_column less_than_ten
0 item1 cat1 5 1
1 item2 cat1 1 1
2 item3 cat1 8 1
3 item4 cat2 3 1
4 item5 cat2 731 0
5 item6 cat2 189 1
6 item7 cat2 9 1
在这种情况下我不会使用 pd.cut
:
df['less_than_ten'] = df.third_column.le(10).astype(np.uint8)
df.loc[df.second_column=='cat2','less_than_ten'] = \
df.loc[df.second_column=='cat2','third_column'].le(10).astype(np.uint8) + 2
结果:
In [99]: df
Out[99]:
first_column second_column third_column less_than_ten
0 item1 cat1 5 1
1 item2 cat1 1 1
2 item3 cat1 8 1
3 item4 cat2 3 3
4 item5 cat2 731 2
5 item6 cat2 189 2
6 item7 cat2 9 3
虽然我完全理解我提出的解决方案看起来像黑客并且给出的数字与您的不同,但我仍然在这里提供它:
df['less_than_ten'] = (df.second_column=='cat1').astype(int) +\
(df.third_column<10).astype(int)
# first_column second_column third_column less_than_ten
#0 item1 cat1 5 2
#1 item2 cat1 1 2
#2 item3 cat1 8 2
#3 item4 cat2 3 1
#4 item5 cat2 731 0
#5 item6 cat2 189 0
#6 item7 cat2 9 1
括号中的条件可以任意复杂,只要是布尔值即可(True
/False
)。
我有一个 pandas DataFrame 如下:
import pandas as pd
import numpy as np
data = {"first_column": ["item1", "item2", "item3", "item4", "item5", "item6", "item7"],
"second_column": ["cat1", "cat1", "cat1", "cat2", "cat2", "cat2", "cat2"],
"third_column": [5, 1, 8, 3, 731, 189, 9]}
df = pd.DataFrame(data)
df
first_column second_column third_column
0 item1 cat1 5
1 item2 cat1 1
2 item3 cat1 8
3 item4 cat2 3
4 item5 cat2 731
5 item6 cat2 189
6 item7 cat2 9
现在,假设我想使用 pandas.cut()
创建第四列来显示第三列的分类。这里,我在每一行标注third_column
中的元素是否小于等于十,<=10
。
df["less_than_ten"]= pd.cut(df.third_column, [-np.inf, 10, np.inf], labels=(1,0))
现在生成的数据框是:
first_column second_column third_column less_than_ten
0 item1 cat1 5 1
1 item2 cat1 1 1
2 item3 cat1 8 1
3 item4 cat2 3 1
4 item5 cat2 731 0
5 item6 cat2 189 0
6 item7 cat2 9 1
问题:请注意第二列 second_column
,类别为 cat1
和 cat2
。我将如何使用 pandas.cut()
根据 second_column
中的 "class" 对这些值进行重新分类?
更重要的是,假设我想要更复杂的间隔,例如小于或等于 500 le(500) 且大于或等于 20 ge(20)?这将如何完成?在这种情况下,应该有一个 1 标记为分组:
first_column second_column third_column less_than_ten
0 item1 cat1 5 1
1 item2 cat1 1 1
2 item3 cat1 8 1
3 item4 cat2 3 1
4 item5 cat2 731 0
5 item6 cat2 189 1
6 item7 cat2 9 1
在这种情况下我不会使用 pd.cut
:
df['less_than_ten'] = df.third_column.le(10).astype(np.uint8)
df.loc[df.second_column=='cat2','less_than_ten'] = \
df.loc[df.second_column=='cat2','third_column'].le(10).astype(np.uint8) + 2
结果:
In [99]: df
Out[99]:
first_column second_column third_column less_than_ten
0 item1 cat1 5 1
1 item2 cat1 1 1
2 item3 cat1 8 1
3 item4 cat2 3 3
4 item5 cat2 731 2
5 item6 cat2 189 2
6 item7 cat2 9 3
虽然我完全理解我提出的解决方案看起来像黑客并且给出的数字与您的不同,但我仍然在这里提供它:
df['less_than_ten'] = (df.second_column=='cat1').astype(int) +\
(df.third_column<10).astype(int)
# first_column second_column third_column less_than_ten
#0 item1 cat1 5 2
#1 item2 cat1 1 2
#2 item3 cat1 8 2
#3 item4 cat2 3 1
#4 item5 cat2 731 0
#5 item6 cat2 189 0
#6 item7 cat2 9 1
括号中的条件可以任意复杂,只要是布尔值即可(True
/False
)。