我有一个DataFrame df
>>df
LED CFL Incan Hall Reading
0 3 2 1 100 150
1 2 3 1 150 100
2 0 1 3 200 150
3 1 2 4 300 250
4 3 3 1 170 100
我想创建另外两个包含lists
的列,一个用于"Hall"
,另一个用于"Reading"
>>df_output
LED CFL Incan Hall Reading Hall_List Reading_List
0 3 2 1 100 150 [0,2,0] [2,0,0]
1 2 3 1 150 100 [0,3,0] [2,0,0]
2 0 1 3 200 150 [0,1,0] [0,0,2]
3 1 2 4 300 250 [0,2,0] [1,0,0]
4 3 3 1 100 100 [0,2,0] [2,0,0]
列表中的每个值都填充如下:
cfl_rating = 50
led_rating = 100
incan_rating = 25
对于Hall_List
:
偏好是CFL> LED>印加。并且只使用其中一个(CFL或LED或印加)。
我们首先检查CFL != 0
是否为True
,然后我们计算min(ceil(Hall/CFL_rating),CFL)
。对于index=0
,这个评估为2.因此我们有[0,2,0]而对于index=2
我们有[0,1,0]。
类似于Reading_List
,首选项是LED>印加> CFL。
对于index=2
,我们有LED == 0
,因此我们计算min(ceil(Reading/Incan_rating),Incan)
,因此Reading_List为[0,0,2]
我的问题是: 这样做有" pandas / pythony-way" 吗?我目前正在遍历每一行,并使用if-elif-else条件来赋值。
我的代码段如下所示:
#Hall_List
for i in range(df.shape[0]):
Hall = []
if (df['CFL'].iloc[i] != 0):
Hall.append(0)
Hall.append(min((math.ceil(df['Hall'].iloc[i]/cfl_rating)),df['CFL'].iloc[i]))
Hall.append(0)
elif (df['LED'].iloc[i] != 0):
Hall.append(min((math.ceil(df['Hall'].iloc[i]/led_rating)),df['LED'].iloc[i]))
Hall.append(0)
Hall.append(0)
else:
Hall.append(0)
Hall.append(0)
Hall.append(min((math.ceil(df['Hall'].iloc[i]/incan_rating)),df['Incan'].iloc[i]))
df['Hall_List'].iloc[i] = Hall
这真的很慢,而且对于编码这个问题肯定是一种糟糕的方式。
答案 0 :(得分:0)
为简单起见,我缩短了你的公式,但你应该使用df.apply(axis = 1)
这需要每一行并返回和ndarray,然后你可以应用你想要的任何功能:
df = pd.DataFrame([[3, 2, 1, 100, 150], [2, 3, 1, 150, 100]], columns=['LED', 'CFL', 'Incan', 'Hall', 'Reading'])
def create_list(ndarray):
if ndarray[1] != 0:
result = [0, ndarray[1], 0]
else:
result = [ndarray[2], 0, 0]
return result
df['Hall_List'] = df.apply(lambda x: create_list(x), axis=1)
只需将功能更改为您喜欢的任何内容。
In[49]: df
Out[49]:
LED CFL Incan Hall Reading Hall_List
0 3 2 1 100 150 [0, 2, 0]
1 2 3 1 150 100 [0, 3, 0]
希望这会有所帮助