我有问题找到最好的' python方式'返回pandas DataFrame中值的位置(行|列)。
我有一个数字列表......
list = [1,2,3,4,5,8]
和一只pandas Dataframe。
df = pd.DataFrame({'A':[1,3,8,8], 'B':[3,3,2,8],'x':[0.4,0.3,0.5,0.8]})
df
Out[2]:
A B x
0 1 3 0.4
1 3 3 0.3
2 8 2 0.5
3 8 8 0.8
我会使用列表中的每个数字遍历DataFrame,但我认为这不是最好的python方式。
我不知道要解决这个问题...我很高兴,如果你有一些搜索关键词,我可以解决问题。
稍后我将复制该行,其中包括单个数字和新数据框架中数字背后的值。
目标是获得以下输出......
dfnew
SingleNumber AorB x
0 1 3 0.4
1 2 8 0.5
我很高兴能找到解决这个问题的每一个信息。如果您需要其他背景信息,请与我们联系。
PS:我是初学者:)
答案 0 :(得分:2)
考虑到你的起点(注意我已将list
重命名为data
,否则会影响内置内容:
data = [1,2,3,4,5,8]
df = pd.DataFrame({'A':[1,3,8,8], 'B':[3,3,2,8],'x':[0.4,0.3,0.5,0.8]})
首先,展平您的框架,以便您可以使用单个列:
flattened = pd.melt(df, value_vars=['A', 'B'])
这给了你:
variable value
0 A 1
1 A 3
2 A 8
3 A 8
4 B 3
5 B 3
6 B 2
7 B 8
然后过滤data
中的值(在这种情况下,它返回相同的数据帧,因此我不会复制/粘贴与上面相同的结果):
in_data = flattened[flattened.value.isin(data)]
然后删除所有重复值:
only_once = in_data.drop_duplicates(subset='value', keep=False)
这给了你:
variable value
0 A 1
6 B 2
然后您可以使用该索引返回原始DF:
new_df = df.iloc[only_once.index // len(df.columns)]
这给了你:
A B x
0 1 3 0.4
2 8 2 0.5
然后分配列......
new_df['single_number'] = only_once.value.values
最终结果是:
A B x single_number
0 1 3 0.4 1
2 8 2 0.5 2
如果您真的想要新的索引值,则会保留原始索引值,然后查看.reset_index(drop=True)
以获得0和1。
在以下评论之后获取原始数据的更智能方法:
例如......让我将df更改为
df = pd.DataFrame({'A':[1,3,8,5], 'B':[3,3,2,8],'x':[0.4,0.3,0.5,0.8]})
。当我计算new_df
时,我得到了错误的结果。
请注意,这不包括检查列表中的值。
使用重置索引展平列,以便以后可以使用该列,并从中删除所有重复的值。
df = pd.DataFrame({'A':[1,3,8,5], 'B':[3,3,2,8],'x':[0.4,0.3,0.5,0.8]})
unique = pd.melt(
df.reset_index(),
id_vars='index',
value_vars=['A', 'B'],
value_name='SingleNumber'
).drop_duplicates(subset='SingleNumber', keep=False)
这给了你:
index variable value
0 0 A 1
3 3 A 5
6 2 B 2
然后使用其索引和先前保留的索引列将其与原始框架合并。
new_df = df.merge(unique, left_index=True, right_on='index')
你最终得到:
A B x index variable SingleNumber
0 1 3 0.4 0 A 1
6 8 2 0.5 2 B 2
3 5 8 0.8 3 A 5
然后根据需要删除或重命名列或重置索引等。
答案 1 :(得分:1)
我有一个解决方案,但没有太多时间来解释:
dfnew = pd.DataFrame([1,2,3,4,5,8], columns=['SingleNumber'])
def func(row):
match = df_values[df_values == row['SingleNumber']]
if len(match) == 1:
idx = match.index.get_level_values(0)[0]
col = match.index.get_level_values(1)[0]
return pd.Series({
'AorB': df.loc[idx, 'A' if col == 'B' else 'B'],
'x': df.loc[idx, 'x']
})
dfnew.join(dfnew.apply(func, axis=1)).dropna()
如果有任何需要解释,请告诉我!