- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在寻找更好的解决方案来解决我在研究中遇到的数据处理问题。我有一个 Pandas DataFrame,我试图提取组(Frame)中特定列(Z)的所有值,保留不同列(名称)给出的 ID 对。最终结果不必再是 Pandas 对象,但最好完全在 Pandas 中完成此操作。通过示例可以最清楚地了解任务。
d=[['7500', '3.2900', '0', 'apple'],['7500', '-0.3500', '1', 'orange'],['7500', '-4.1400', '2', 'orange'],['7501', '3.4625', '0', 'apple'],['7501', '-0.2275', '1', 'apple'],['7501', '-4.1175', '2', 'orange'],['7502', '3.2087', '0', 'orange'],['7502', '-0.7313', '1', 'apple'],['7502', '-4.7513', '2', 'apple']]
df=pd.DataFrame(d, columns=["Frame","Z","Order","Name"])
>>> df
Frame Z Order Name
0 7500 3.2900 0 apple
1 7500 -0.3500 1 orange
2 7500 -4.1400 2 orange
3 7501 3.4625 0 apple
4 7501 -0.2275 1 apple
5 7501 -4.1175 2 orange
6 7502 3.2087 0 orange
7 7502 -0.7313 1 apple
8 7502 -4.7513 2 apple
因此,对于每个框架组,我想根据“顺序”列采用独特的组合,因此对于框架 7500 组,这将是:
(0,1)
(0,2)
(1,2)
但请注意,每组中的行数可以在 1 到 5 之间变化,而不仅仅是 0、1、2。然后我会跟踪这些对的“名称”值,
(apple, orange)
(apple, orange)
(orange, orange)
然后我会取出这些相应对的“Z”值,如下所示:
( 3.2900, -0.3500)
( 3.2900, -4.1400)
(-0.3500, -4.1400)
现在,最后,结合这些数据,我想要基于“名称”列的每个唯一对的两个列表。在本例中,我们将这些列表称为first_vals和second_vals,但这完全是任意的,
(apple, orange)
first_vals = [3.2900, 3.2900, ...]
second_vals = [-0.3500, -4.1400, ...]
(orange, orange)
first_vals = [-0.3500, ...]
second_vals = [-4.140, ...]
这是我使用字典想出的一个解决方案。它有效,但我认为它非常丑陋,并且隐藏了字典键中的数据结构。此示例依赖于按 Order 列对组进行预排序,但这实际上没有问题。
from itertools import combinations
from collections import defaultdict
zpairs = defaultdict(list)
for name, group in df.groupby(["Frame"]):
order_pairs = combinations(range(len(group)), 2)
zvals = group["Z"].values
rowids = group["Name"].values
for pair in order_pairs:
pair_str = str(rowids[pair[0]])+"-"+str(rowids[pair[1]])
zpairs[pair_str+"-first"].append(zvals[pair[0]])
zpairs[pair_str+"-second"].append(zvals[pair[1]])
该代码的结果如下所示:
>>> dict(zpairs)
{'apple-apple-first': ['3.4625', '-0.7313'],
'apple-apple-second': ['-0.2275', '-4.7513'],
'apple-orange-first': ['3.2900', '3.2900', '3.4625', '-0.2275'],
'apple-orange-second': ['-0.3500', '-4.1400', '-4.1175', '-4.1175'],
'orange-apple-first': ['3.2087', '3.2087'],
'orange-apple-second': ['-0.7313', '-4.7513'],
'orange-orange-first': ['-0.3500'],
'orange-orange-second': ['-4.1400']}
有没有一种方法可以处理我的数据框,不依赖字典,也不使用字典键来存储数据?这实际上并不是为了提高性能,但这会很有帮助。
最佳答案
这是一个分两步完成的 pandas 方法:
第 1 步
为了获取名称和 z 值对,我将编写一个辅助函数 get_group_pairs
,我将在执行 groupby
时调用该函数。我正在执行与您在循环中执行的操作类似的过程,但在 DataFrame
中返回输出:
def get_group_pairs(grp):
pairs = combinations(grp.index, 2)
data = [grp.loc[p, ('Name', 'Z')].values.flatten('F') for p in pairs]
return pd.DataFrame(data, columns=['Name1', 'Name2', 'Z1', 'Z2'])
namepairs = df.groupby('Frame').apply(get_group_pairs).reset_index(level=1, drop=True)
reset_index
纯粹是为了删除不必要的索引级别,以便中间输出看起来不错。如果您不关心中间输出,则没有必要。中间输出namepairs
:
Name1 Name2 Z1 Z2
Frame
7500 apple orange 3.2900 -0.3500
7500 apple orange 3.2900 -4.1400
7500 orange orange -0.3500 -4.1400
7501 apple apple 3.4625 -0.2275
7501 apple orange 3.4625 -4.1175
7501 apple orange -0.2275 -4.1175
7502 orange apple 3.2087 -0.7313
7502 orange apple 3.2087 -4.7513
7502 apple apple -0.7313 -4.7513
第 2 步
与步骤 1 中相同的辅助函数/groupby
/apply
模式。本质上,我只是使用两个名称进行分组,然后将两个 Z 列转换为列表:
def merge_zpairs(grp):
data = {'Z1': grp['Z1'].tolist(), 'Z2': grp['Z2'].tolist()}
return pd.Series(data)
zpairs = namepairs.groupby(['Name1', 'Name2']).apply(merge_zpairs).reset_index()
同样,reset_index
并不是绝对必要的。如果没有它,您将得到一个由名称对组成的 MultiIndex
。这将产生最终输出 zpairs
:
Name1 Name2 Z1 Z2
0 apple apple [3.4625, -0.7313] [-0.2275, -4.7513]
1 apple orange [3.2900, 3.2900, 3.4625, -0.2275] [-0.3500, -4.1400, -4.1175, -4.1175]
2 orange apple [3.2087, 3.2087] [-0.7313, -4.7513]
3 orange orange [-0.3500] [-4.1400]
组合代码
为方便起见,以下是步骤 1 和 2 中组合的代码:
def get_group_pairs(grp):
pairs = combinations(grp.index, 2)
data = [grp.loc[p, ('Name', 'Z')].values.flatten('F') for p in pairs]
return pd.DataFrame(data, columns=['Name1', 'Name2', 'Z1', 'Z2'])
def merge_zpairs(grp):
data = {'Z1': grp['Z1'].tolist(), 'Z2': grp['Z2'].tolist()}
return pd.Series(data)
namepairs = df.groupby('Frame').apply(get_group_pairs).reset_index(level=1, drop=True)
zpairs = namepairs.groupby(['Name1', 'Name2']).apply(merge_zpairs).reset_index()
获取字典
通过对步骤 2 的代码进行一些细微修改,您可以获得与您的类似的字典结构,尽管并不完全相同。本质上,不要使用 reset_index
,而是使用 to_dict
和 orient='index'
:
zpairs = namepairs.groupby(['Name1', 'Name2']).apply(merge_zpairs)
zpairs_dict = zpairs.to_dict(orient='index')
这会产生一个字典的字典:第一个键是一对名称,第二个键是您想要的 Z 值。例如,'apple-apple-first'
的语法为:
zpairs_dict[('apple', 'apple')]['Z1']
关于python - 如何使用 Pandas 处理行对并在没有字典的情况下保留 ID 列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37554460/
猫f1.txt阿曼维沙尔阿杰贾伊维杰拉胡尔曼尼什肖比特批评塔夫林现在输出应该符合上面给定的条件 最佳答案 您可以在文件读取循环中设置一个计数器并打印它, 计数=0 读取行时做 让我们数一数++ if
我正在尝试查找文件 1 和文件 2 中的共同行。如果公共(public)行存在,我想写入文件 2 中的行,否则打印文件 1 中的非公共(public)行。fin1 和 fin2 是这里的文件句柄。它读
我有这个 SQL 脚本: CREATE TABLE `table_1` ( `IDTable_1` int(11) NOT NULL, PRIMARY KEY (`IDTable_1`) );
我有 512 行要插入到数据库中。我想知道提交多个插入内容是否比提交一个大插入内容有任何优势。例如 1x 512 行插入 -- INSERT INTO mydb.mytable (id, phonen
如何从用户中选择user_id,SUB(row, row - 1),其中user_id=@userid我的表用户,id 为 1、3、4、10、11、23...(不是++) --id---------u
我曾尝试四处寻找解决此问题的最佳方法,但我找不到此类问题的任何先前示例。 我正在构建一个基于超本地化的互联网购物中心,该区域分为大约 3000 个区域。每个区域包含大约 300 个项目。它们是相似的项
preg_match('|phpVersion = (.*)\n|',$wampConfFileContents,$result); $phpVersion = str_replace('"','',
我正在尝试创建一个正则表达式,使用“搜索并替换全部”删除 200 个 txt 文件的第一行和最后 10 行 我尝试 (\s*^(\h*\S.*)){10} 删除包含的前 10 行空白,但效果不佳。 最
下面的代码从数据库中获取我需要的信息,但没有打印出所有信息。首先,我知道它从表中获取了所有正确的信息,因为我已经在 sql Developer 中尝试过查询。 public static void m
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我试图在两个表中插入记录,但出现异常。您能帮我解决这个问题吗? 首先我尝试了下面的代码。 await _testRepository.InsertAsync(test); await _xyzRepo
这个基本的 bootstrap CSS 显示 1 行 4 列: Text Text Text
如果我想从表中检索前 10 行,我将使用以下代码: SELECT * FROM Persons LIMIT 10 我想知道的是如何检索前 10 个结果之后的 10 个结果。 如果我在下面执行这段代码,
今天我开始使用 JexcelApi 并遇到了这个:当您尝试从特定位置获取元素时,不是像您通常期望的那样使用sheet.getCell(row,col),而是使用sheet.getCell(col,ro
我正在尝试在我的网站上开发一个用户个人资料系统,其中包含用户之前发布的 3 个帖子。我可以让它选择前 3 条记录,但它只会显示其中一条。我是不是因为凌晨 2 点就想编码而变得愚蠢? query($q)
我在互联网上寻找答案,但找不到任何答案。 (我可能问错了?)我有一个看起来像这样的表: 我一直在使用查询: SELECT title, date, SUM(money) FROM payments W
我有以下查询,我想从数据库中获取 100 个项目,但 host_id 多次出现在 urls 表中,我想每个 host_id 从该表中最多获取 10 个唯一行。 select * from urls j
我的数据库表中有超过 500 行具有特定日期。 查询特定日期的行。 select * from msgtable where cdate='18/07/2012' 这将返回 500 行。 如何逐行查询
我想使用 sed 从某一行开始打印 n 行、跳过 n 行、打印 n 行等,直到文本文件结束。例如在第 4 行声明,打印 5-9,跳过 10-14,打印 15-19 等 来自文件 1 2 3 4 5 6
我目前正在执行验证过程来检查用户的旧密码,但问题是我无法理解为什么我的查询返回零行,而预期它有 1 行。另一件事是,即使我不将密码文本转换为 md5,哈希密码仍然得到正确的答案,但我不知道为什么会发生
我是一名优秀的程序员,十分优秀!